quarchpy 2.2.15__py2.py3-none-any.whl → 2.2.16__py2.py3-none-any.whl

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.
Files changed (85) hide show
  1. quarchpy/__pycache__/__init__.cpython-310.pyc +0 -0
  2. quarchpy/__pycache__/_version.cpython-310.pyc +0 -0
  3. quarchpy/__pycache__/connection.cpython-310.pyc +0 -0
  4. quarchpy/__pycache__/install_qps.cpython-310.pyc +0 -0
  5. quarchpy/_version.py +1 -1
  6. quarchpy/config_files/__pycache__/__init__.cpython-310.pyc +0 -0
  7. quarchpy/config_files/__pycache__/quarch_config_parser.cpython-310.pyc +0 -0
  8. quarchpy/connection_specific/__pycache__/StreamChannels.cpython-310.pyc +0 -0
  9. quarchpy/connection_specific/__pycache__/__init__.cpython-310.pyc +0 -0
  10. quarchpy/connection_specific/__pycache__/connection_QIS.cpython-310.pyc +0 -0
  11. quarchpy/connection_specific/__pycache__/connection_QPS.cpython-310.pyc +0 -0
  12. quarchpy/connection_specific/__pycache__/connection_ReST.cpython-310.pyc +0 -0
  13. quarchpy/connection_specific/__pycache__/connection_Serial.cpython-310.pyc +0 -0
  14. quarchpy/connection_specific/__pycache__/connection_TCP.cpython-310.pyc +0 -0
  15. quarchpy/connection_specific/__pycache__/connection_USB.cpython-310.pyc +0 -0
  16. quarchpy/connection_specific/__pycache__/mDNS.cpython-310.pyc +0 -0
  17. quarchpy/connection_specific/connection_QIS.py +1510 -1485
  18. quarchpy/connection_specific/jdk_jres/__pycache__/__init__.cpython-310.pyc +0 -0
  19. quarchpy/connection_specific/jdk_jres/__pycache__/fix_permissions.cpython-310.pyc +0 -0
  20. quarchpy/connection_specific/serial/__pycache__/__init__.cpython-310.pyc +0 -0
  21. quarchpy/connection_specific/serial/__pycache__/serialposix.cpython-310.pyc +0 -0
  22. quarchpy/connection_specific/serial/__pycache__/serialutil.cpython-310.pyc +0 -0
  23. quarchpy/connection_specific/serial/tools/__pycache__/__init__.cpython-310.pyc +0 -0
  24. quarchpy/connection_specific/serial/tools/__pycache__/list_ports.cpython-310.pyc +0 -0
  25. quarchpy/connection_specific/serial/tools/__pycache__/list_ports_common.cpython-310.pyc +0 -0
  26. quarchpy/connection_specific/serial/tools/__pycache__/list_ports_linux.cpython-310.pyc +0 -0
  27. quarchpy/connection_specific/serial/tools/__pycache__/list_ports_posix.cpython-310.pyc +0 -0
  28. quarchpy/debug/__pycache__/SystemTest.cpython-310.pyc +0 -0
  29. quarchpy/debug/__pycache__/__init__.cpython-310.pyc +0 -0
  30. quarchpy/debug/__pycache__/versionCompare.cpython-310.pyc +0 -0
  31. quarchpy/device/__pycache__/__init__.cpython-310.pyc +0 -0
  32. quarchpy/device/__pycache__/device.cpython-310.pyc +0 -0
  33. quarchpy/device/__pycache__/device_fixture_idn_info.cpython-310.pyc +0 -0
  34. quarchpy/device/__pycache__/device_idn_info.cpython-310.pyc +0 -0
  35. quarchpy/device/__pycache__/device_network_info.cpython-310.pyc +0 -0
  36. quarchpy/device/__pycache__/discovered_device.cpython-310.pyc +0 -0
  37. quarchpy/device/__pycache__/packet_processing.cpython-310.pyc +0 -0
  38. quarchpy/device/__pycache__/quarchArray.cpython-310.pyc +0 -0
  39. quarchpy/device/__pycache__/quarchPPM.cpython-310.pyc +0 -0
  40. quarchpy/device/__pycache__/quarchQPS.cpython-310.pyc +0 -0
  41. quarchpy/device/__pycache__/scanDevices.cpython-310.pyc +0 -0
  42. quarchpy/device/quarchPPM.py +7 -10
  43. quarchpy/disk_test/__pycache__/AbsDiskFinder.cpython-310.pyc +0 -0
  44. quarchpy/disk_test/__pycache__/DiskTargetSelection.cpython-310.pyc +0 -0
  45. quarchpy/disk_test/__pycache__/__init__.cpython-310.pyc +0 -0
  46. quarchpy/disk_test/__pycache__/iometerDiskFinder.cpython-310.pyc +0 -0
  47. quarchpy/docs/CHANGES.rst +4 -0
  48. quarchpy/docs/_build/doctrees/CHANGES.doctree +0 -0
  49. quarchpy/docs/_build/doctrees/environment.pickle +0 -0
  50. quarchpy/docs/_build/doctrees/source/changelog.doctree +0 -0
  51. quarchpy/docs/_build/doctrees/source/quarchpy.connection_specific.doctree +0 -0
  52. quarchpy/docs/_build/doctrees/source/quarchpy.device.doctree +0 -0
  53. quarchpy/docs/_build/doctrees/source/quarchpy.qis.doctree +0 -0
  54. quarchpy/docs/_build/html/CHANGES.html +163 -157
  55. quarchpy/docs/_build/html/_sources/CHANGES.rst.txt +4 -0
  56. quarchpy/docs/_build/html/genindex.html +7 -3
  57. quarchpy/docs/_build/html/index.html +80 -79
  58. quarchpy/docs/_build/html/objects.inv +0 -0
  59. quarchpy/docs/_build/html/searchindex.js +1 -1
  60. quarchpy/docs/_build/html/source/changelog.html +243 -236
  61. quarchpy/docs/_build/html/source/quarchpy.connection_specific.html +12 -3
  62. quarchpy/docs/_build/html/source/quarchpy.device.html +8 -16
  63. quarchpy/docs/_build/html/source/quarchpy.html +2 -0
  64. quarchpy/docs/_build/html/source/quarchpy.qis.html +12 -3
  65. quarchpy/fio/__pycache__/FIO_interface.cpython-310.pyc +0 -0
  66. quarchpy/fio/__pycache__/__init__.cpython-310.pyc +0 -0
  67. quarchpy/install_qps.py +99 -62
  68. quarchpy/iometer/__pycache__/__init__.cpython-310.pyc +0 -0
  69. quarchpy/iometer/__pycache__/gen_iometer_template.cpython-310.pyc +0 -0
  70. quarchpy/iometer/__pycache__/iometerFuncs.cpython-310.pyc +0 -0
  71. quarchpy/qis/__pycache__/StreamHeaderInfo.cpython-310.pyc +0 -0
  72. quarchpy/qis/__pycache__/__init__.cpython-310.pyc +0 -0
  73. quarchpy/qis/__pycache__/qisFuncs.cpython-310.pyc +0 -0
  74. quarchpy/qps/__pycache__/__init__.cpython-310.pyc +0 -0
  75. quarchpy/qps/__pycache__/qpsFuncs.cpython-310.pyc +0 -0
  76. quarchpy/qps/qpsFuncs.py +4 -0
  77. quarchpy/user_interface/__pycache__/__init__.cpython-310.pyc +0 -0
  78. quarchpy/user_interface/__pycache__/user_interface.cpython-310.pyc +0 -0
  79. quarchpy/utilities/__pycache__/TestCenter.cpython-310.pyc +0 -0
  80. quarchpy/utilities/__pycache__/TimeValue.cpython-310.pyc +0 -0
  81. quarchpy/utilities/__pycache__/__init__.cpython-310.pyc +0 -0
  82. {quarchpy-2.2.15.dist-info → quarchpy-2.2.16.dist-info}/METADATA +15 -2
  83. {quarchpy-2.2.15.dist-info → quarchpy-2.2.16.dist-info}/RECORD +85 -85
  84. {quarchpy-2.2.15.dist-info → quarchpy-2.2.16.dist-info}/WHEEL +1 -1
  85. {quarchpy-2.2.15.dist-info → quarchpy-2.2.16.dist-info}/top_level.txt +0 -0
quarchpy/install_qps.py CHANGED
@@ -1,3 +1,4 @@
1
+ import logging
1
2
  import os
2
3
  import sys
3
4
  import zipfile
@@ -5,8 +6,10 @@ import requests
5
6
  import shutil
6
7
  import xml.etree.ElementTree as ET
7
8
 
9
+ from quarchpy.user_interface import printText, requestDialog
10
+
8
11
  # --- Configuration ---
9
- QPS_VERSION_FOR_DOWNLOAD = "1.49"
12
+ QPS_VERSION_FOR_DOWNLOAD = "1.50"
10
13
  # URLs for the separate ZIP files.
11
14
  QPS_DOWNLOAD_URL = f"https://quarch.com/software_update/qps/QPS_{QPS_VERSION_FOR_DOWNLOAD}.zip"
12
15
  JDK_JRE_DOWNLOAD_URL = "https://quarch.com/software_update/qps/jdk_jres.zip"
@@ -26,10 +29,29 @@ EXTRACTION_FOLDER_QPS = os.path.join(TARGET_DIR, "QPS")
26
29
  EXTRACTION_FOLDER_JDK_JRE = os.path.join(TARGET_DIR, "jdk_jres")
27
30
 
28
31
 
32
+ def get_installed_qps_version(qps_folder):
33
+ """Reads the appVersion from the app.properties file."""
34
+ properties_file = os.path.join(qps_folder, "app.properties")
35
+ if not os.path.exists(properties_file):
36
+ return None # File doesn't exist, can't determine version
37
+
38
+ try:
39
+ with open(properties_file, 'r') as f:
40
+ for line in f:
41
+ if line.strip().startswith("appVersion="):
42
+ # Split the line at '=' and return the version part
43
+ return line.split('=', 1)[1].strip()
44
+ except Exception as e:
45
+ printText(f" - Warning: Could not read version from {properties_file}. Error: {e}")
46
+ return None # Error reading file
47
+
48
+ return None # Version not found in the file
49
+
50
+
29
51
  def find_qps():
30
52
  """
31
- Checks for QPS and JDK/JRE. If any are missing, it attempts an online or
32
- offline installation of the required components.
53
+ Checks for QPS and JDK/JRE. If any are missing or outdated, it attempts an
54
+ online or offline installation of the required components.
33
55
  """
34
56
  qps_jar = "qps.jar"
35
57
  qps_path = os.path.join(EXTRACTION_FOLDER_QPS, qps_jar)
@@ -52,43 +74,58 @@ def find_qps():
52
74
  if jdk_folder_name:
53
75
  jdk_jre_check_file = os.path.join(EXTRACTION_FOLDER_JDK_JRE, jdk_folder_name, "bin", java_executable_name)
54
76
 
55
- qps_found = os.path.exists(qps_path)
77
+ # --- Component Verification ---
78
+ qps_jar_exists = os.path.exists(qps_path)
79
+ installed_qps_version = get_installed_qps_version(EXTRACTION_FOLDER_QPS)
80
+
81
+ # Check if the required version string starts with the installed version number.
82
+ # This handles cases like required "1.48.1-SNAPSHOT" vs. installed "1.48".
83
+ qps_version_ok = False
84
+ if installed_qps_version:
85
+ qps_version_ok = QPS_VERSION_FOR_DOWNLOAD.startswith(installed_qps_version)
86
+
87
+ qps_ok = qps_jar_exists and qps_version_ok
56
88
  jdk_found = jdk_jre_check_file and os.path.exists(jdk_jre_check_file)
57
89
 
58
- if qps_found and jdk_found:
90
+ if qps_ok and jdk_found:
91
+ logging.info(f"QPS version {installed_qps_version} and JDK/JRE are correctly installed.")
59
92
  return True
60
93
 
61
- print("--- Missing Components Detected ---")
62
- qps_needed = not qps_found
94
+ printText("--- Missing or Outdated Components Detected ---")
95
+ qps_needed = not qps_ok
63
96
  jdk_jre_needed = not jdk_found
64
- if qps_needed:
65
- print("Quarch Power Studio (QPS) is not installed.")
97
+
98
+ if not qps_jar_exists:
99
+ printText("Quarch Power Studio (QPS) is not installed.")
100
+ elif not qps_version_ok:
101
+ printText(f"QPS requires an update. (Installed: {installed_qps_version or 'Unknown'}, Required: {QPS_VERSION_FOR_DOWNLOAD})")
102
+
66
103
  if jdk_jre_needed:
67
- print("Required Java JDK/JRE Binaries are not installed.")
104
+ printText("Required Java JDK/JRE Binaries are not installed.")
68
105
 
69
106
  # --- Installation Logic ---
70
107
  installation_successful = False
71
108
  response = ""
72
109
  if is_network_connection_available():
73
110
  network_available = True
74
- print("\nAttempting online installation...")
75
- response = input("Would you like to download and install the missing components? (y/n): ").lower()
111
+ printText("\nAttempting online installation...")
112
+ response = requestDialog("Would you like to download and install the missing/outdated components? (y/n): ").lower()
76
113
 
77
114
  if response == 'y':
78
115
  qps_url_to_use = QPS_DOWNLOAD_URL
79
116
 
80
117
  if qps_needed and not is_download_url_valid(qps_url_to_use):
81
- print(f"The download url {qps_url_to_use} is not valid.")
82
- print(f"Defaulting to URL for the latest version of QPS: \n{QPS_DOWNLOAD_URL_LATEST}")
118
+ printText(f"The download url {qps_url_to_use} is not valid.")
119
+ printText(f"Defaulting to URL for the latest version of QPS: \n{QPS_DOWNLOAD_URL_LATEST}")
83
120
 
84
121
  latest_version = get_latest_qps_version()
85
122
  if latest_version != QPS_VERSION_FOR_DOWNLOAD:
86
- print(f"Warning! The version of QuarchPy you are using does not officially support the latest version of QPS ({latest_version}).")
87
- print("Please consider upgrading QuarchPy.")
88
- proceed = input("Would you like to proceed with downloading the latest version? (y/n): ").lower()
123
+ printText(f"Warning! The version of QuarchPy you are using does not officially support the latest version of QPS ({latest_version}).")
124
+ printText("Please consider upgrading QuarchPy.")
125
+ proceed = requestDialog("Would you like to proceed with downloading the latest version? (y/n): ").lower()
89
126
 
90
127
  if proceed != 'y':
91
- print("Installation cancelled by user.")
128
+ printText("Installation cancelled by user.")
92
129
  qps_url_to_use = None
93
130
  else:
94
131
  qps_url_to_use = QPS_DOWNLOAD_URL_LATEST
@@ -101,34 +138,34 @@ def find_qps():
101
138
  else:
102
139
  installation_successful = install_online(qps_url_to_use, JDK_JRE_DOWNLOAD_URL, qps_needed, jdk_jre_needed)
103
140
  else:
104
- print("\nNo internet connection detected.")
141
+ printText("\nNo internet connection detected.")
105
142
  network_available = False
106
143
 
107
144
  if response == 'n' or not network_available:
108
- print("To install manually, download the required files:")
145
+ printText("To install manually, download the required files:")
109
146
  if qps_needed:
110
- print(f" - QPS: {QPS_DOWNLOAD_URL} (or latest: {QPS_DOWNLOAD_URL_LATEST})")
147
+ printText(f" - QPS: {QPS_DOWNLOAD_URL} (or latest: {QPS_DOWNLOAD_URL_LATEST})")
111
148
  if jdk_jre_needed:
112
- print(f" - JDK/JRE: {JDK_JRE_DOWNLOAD_URL}")
149
+ printText(f" - JDK/JRE: {JDK_JRE_DOWNLOAD_URL}")
113
150
 
114
- input("\nPress Enter to Continue after downloading.")
115
- response = input("Would you like to install from the manually downloaded ZIP file(s)? (y/n) ").lower()
151
+ requestDialog("\nPress Enter to Continue after downloading.")
152
+ response = requestDialog("Would you like to install from the manually downloaded ZIP file(s)? (y/n) ").lower()
116
153
  if response == 'y':
117
154
  installation_successful = install_offline(qps_needed, jdk_jre_needed)
118
155
 
119
156
  if not installation_successful:
120
- print("Installation was cancelled or failed.")
157
+ printText("Installation was cancelled or failed.")
121
158
  return False
122
159
 
123
160
  # --- Final Check ---
124
161
  qps_found = os.path.exists(qps_path)
125
162
  jdk_found = jdk_jre_check_file and os.path.exists(jdk_jre_check_file)
126
163
  if (qps_needed and not qps_found) or (jdk_jre_needed and not jdk_found):
127
- print("\nInstallation failed. Some components are still missing.")
128
- print("Please contact Quarch Support for further help: https://quarch.com/contact/")
164
+ printText("\nInstallation failed. Some components are still missing.")
165
+ printText("Please contact Quarch Support for further help: https://quarch.com/contact/")
129
166
  return False
130
167
  else:
131
- print("\nAll required components are now installed.")
168
+ printText("\nAll required components are now installed.")
132
169
  return True
133
170
 
134
171
 
@@ -139,21 +176,21 @@ def install_online(qps_url, jdk_jre_url, qps_needed, jdk_jre_needed):
139
176
 
140
177
  if qps_needed:
141
178
  qps_zip_path = os.path.join(TARGET_DIR, "QPS_download.zip")
142
- print("\n--- Installing QPS ---")
179
+ printText("\n--- Installing QPS ---")
143
180
  if download_file(qps_url, qps_zip_path):
144
181
  qps_success = extract_and_move_qps(qps_zip_path)
145
182
  os.remove(qps_zip_path)
146
- print(f"Cleaned up {qps_zip_path}")
183
+ printText(f"Cleaned up {qps_zip_path}")
147
184
  else:
148
185
  qps_success = False
149
186
 
150
187
  if jdk_jre_needed:
151
188
  jdk_jre_zip_path = os.path.join(TARGET_DIR, "jdk_jre.zip")
152
- print("\n--- Installing JDK/JRE ---")
189
+ printText("\n--- Installing JDK/JRE ---")
153
190
  if download_file(jdk_jre_url, jdk_jre_zip_path):
154
191
  jdk_jre_success = extract_and_move_jdk_jre(jdk_jre_zip_path)
155
192
  os.remove(jdk_jre_zip_path)
156
- print(f"Cleaned up {jdk_jre_zip_path}")
193
+ printText(f"Cleaned up {jdk_jre_zip_path}")
157
194
  else:
158
195
  jdk_jre_success = False
159
196
 
@@ -166,7 +203,7 @@ def install_offline(qps_needed, jdk_jre_needed):
166
203
  jdk_jre_success = not jdk_jre_needed
167
204
 
168
205
  if qps_needed:
169
- print("\nPlease select the QPS ZIP file (e.g., QPS_1.47.zip).")
206
+ printText("\nPlease select the QPS ZIP file (e.g., QPS_1.47.zip).")
170
207
  qps_zip_filepath = prompt_for_zip_path("Select QPS ZIP File")
171
208
  if qps_zip_filepath:
172
209
  qps_success = extract_and_move_qps(qps_zip_filepath)
@@ -174,7 +211,7 @@ def install_offline(qps_needed, jdk_jre_needed):
174
211
  return False # User cancelled
175
212
 
176
213
  if jdk_jre_needed:
177
- print("\nPlease select the JDK/JRE ZIP file (jdk_jre.zip).")
214
+ printText("\nPlease select the JDK/JRE ZIP file (jdk_jre.zip).")
178
215
  jdk_jre_zip_filepath = prompt_for_zip_path("Select JDK/JRE ZIP File")
179
216
  if jdk_jre_zip_filepath:
180
217
  jdk_jre_success = extract_and_move_jdk_jre(jdk_jre_zip_filepath)
@@ -187,7 +224,7 @@ def install_offline(qps_needed, jdk_jre_needed):
187
224
  def download_file(url, destination_path):
188
225
  """Downloads a file from a URL to a destination path with a progress bar."""
189
226
  try:
190
- print(f"Downloading from {url}...")
227
+ printText(f"Downloading from {url}...")
191
228
  with requests.get(url, stream=True, timeout=30) as r:
192
229
  r.raise_for_status()
193
230
  total_size = int(r.headers.get('content-length', 0))
@@ -199,16 +236,16 @@ def download_file(url, destination_path):
199
236
  done = int(50 * downloaded / total_size) if total_size > 0 else 0
200
237
  sys.stdout.write(f"\r[{'=' * done}{' ' * (50 - done)}] {downloaded / (1024 * 1024):.2f} MB")
201
238
  sys.stdout.flush()
202
- print("\nDownload complete.")
239
+ printText("\nDownload complete.")
203
240
  return True
204
241
  except requests.RequestException as e:
205
- print(f"\nError: Failed to download file. {e}")
242
+ printText(f"\nError: Failed to download file. {e}")
206
243
  return False
207
244
 
208
245
  def extract_and_move_qps(zip_filepath):
209
246
  """Extracts QPS from its ZIP and moves it to ...quarchpy\\connection_specific\\QPS."""
210
247
  temp_extract_path = os.path.join(TARGET_DIR, "temp_extract_qps")
211
- print(f"Processing QPS ZIP file: {os.path.basename(zip_filepath)}")
248
+ printText(f"Processing QPS ZIP file: {os.path.basename(zip_filepath)}")
212
249
  try:
213
250
  if os.path.exists(temp_extract_path):
214
251
  shutil.rmtree(temp_extract_path)
@@ -218,22 +255,22 @@ def extract_and_move_qps(zip_filepath):
218
255
 
219
256
  src_qps_folder = temp_extract_path
220
257
  if not os.path.exists(src_qps_folder):
221
- print(f" - Error: 'qps' folder not found in the ZIP. Extraction failed.")
258
+ printText(f" - Error: 'qps' folder not found in the ZIP. Extraction failed.")
222
259
  return False
223
260
 
224
261
  os.makedirs(EXTRACTION_FOLDER_QPS, exist_ok=True)
225
262
  dest_qps_path = EXTRACTION_FOLDER_QPS
226
263
  if os.path.exists(dest_qps_path):
227
- print(f" - Removing old 'qps' folder...")
264
+ printText(f" - Removing old 'qps' folder...")
228
265
  shutil.rmtree(dest_qps_path)
229
- print(f" - Moving 'qps' to '{EXTRACTION_FOLDER_QPS}'...")
266
+ printText(f" - Moving 'qps' to '{EXTRACTION_FOLDER_QPS}'...")
230
267
  shutil.move(os.path.join(src_qps_folder,"qps"), EXTRACTION_FOLDER_QPS)
231
268
  if os.path.exists(src_qps_folder):
232
269
  shutil.rmtree(src_qps_folder)
233
- print("QPS components moved successfully.")
270
+ printText("QPS components moved successfully.")
234
271
  return True
235
272
  except (zipfile.BadZipFile, FileNotFoundError, OSError) as e:
236
- print(f"\nError during QPS file operations: {e}")
273
+ printText(f"\nError during QPS file operations: {e}")
237
274
  return False
238
275
  finally:
239
276
  if os.path.exists(temp_extract_path):
@@ -243,7 +280,7 @@ def extract_and_move_qps(zip_filepath):
243
280
  def extract_and_move_jdk_jre(zip_filepath):
244
281
  """Extracts JDK/JRE from its ZIP and moves all component folders."""
245
282
  temp_extract_path = os.path.join(TARGET_DIR, "temp_extract_jdk_jre")
246
- print(f"Processing JDK/JRE ZIP file: {os.path.basename(zip_filepath)}")
283
+ printText(f"Processing JDK/JRE ZIP file: {os.path.basename(zip_filepath)}")
247
284
  try:
248
285
  if os.path.exists(temp_extract_path):
249
286
  shutil.rmtree(temp_extract_path)
@@ -252,7 +289,7 @@ def extract_and_move_jdk_jre(zip_filepath):
252
289
  zip_ref.extractall(temp_extract_path)
253
290
 
254
291
  os.makedirs(EXTRACTION_FOLDER_JDK_JRE, exist_ok=True)
255
- print(f" - Moving JDK/JRE contents to '{EXTRACTION_FOLDER_JDK_JRE}'...")
292
+ printText(f" - Moving JDK/JRE contents to '{EXTRACTION_FOLDER_JDK_JRE}'...")
256
293
  for item_name in os.listdir(temp_extract_path):
257
294
  src_item = os.path.join(temp_extract_path, item_name)
258
295
  dest_item = os.path.join(EXTRACTION_FOLDER_JDK_JRE, item_name)
@@ -260,10 +297,10 @@ def extract_and_move_jdk_jre(zip_filepath):
260
297
  if os.path.exists(dest_item):
261
298
  shutil.rmtree(dest_item)
262
299
  shutil.move(src_item, dest_item)
263
- print("JDK/JRE components moved successfully.")
300
+ printText("JDK/JRE components moved successfully.")
264
301
  return True
265
302
  except (zipfile.BadZipFile, FileNotFoundError, OSError) as e:
266
- print(f"\nError during JDK/JRE file operations: {e}")
303
+ printText(f"\nError during JDK/JRE file operations: {e}")
267
304
  return False
268
305
  finally:
269
306
  if os.path.exists(temp_extract_path):
@@ -275,7 +312,7 @@ def prompt_for_zip_path(title="Select ZIP File"):
275
312
  try:
276
313
  import tkinter as tk
277
314
  from tkinter import filedialog
278
- print("Opening file dialog...")
315
+ printText("Opening file dialog...")
279
316
  root = tk.Tk()
280
317
  root.withdraw()
281
318
  filepath = filedialog.askopenfilename(
@@ -284,12 +321,12 @@ def prompt_for_zip_path(title="Select ZIP File"):
284
321
  )
285
322
  return filepath
286
323
  except (ImportError, tk.TclError):
287
- print("\nGUI not available. Please provide the path in the command line.")
288
- filepath = input(f"Enter the full path to the '{title}' ZIP file: ")
324
+ printText("\nGUI not available. Please provide the path in the command line.")
325
+ filepath = requestDialog(f"Enter the full path to the '{title}' ZIP file: ")
289
326
  if os.path.isfile(filepath):
290
327
  return filepath
291
328
  else:
292
- print("Error: The provided path is not a valid file.")
329
+ printText("Error: The provided path is not a valid file.")
293
330
  return None
294
331
 
295
332
 
@@ -306,7 +343,7 @@ def get_latest_qps_version():
306
343
  """Fetches the latest QPS version number from the Quarch XML file."""
307
344
  version_xml_url = "https://quarch.com/software_update/qps/current_version_all.xml"
308
345
  try:
309
- print(f"Checking for the latest QPS version from {version_xml_url}...")
346
+ printText(f"Checking for the latest QPS version from {version_xml_url}...")
310
347
  response = requests.get(version_xml_url, timeout=10)
311
348
  response.raise_for_status()
312
349
  root = ET.fromstring(response.text)
@@ -314,34 +351,34 @@ def get_latest_qps_version():
314
351
 
315
352
  if latest_version_element is not None:
316
353
  latest_version = latest_version_element.text
317
- print(f" - Latest version found: {latest_version}")
354
+ printText(f" - Latest version found: {latest_version}")
318
355
  return latest_version
319
356
  else:
320
- print(" - Could not find 'LatestVersion' tag in the XML.")
357
+ printText(" - Could not find 'LatestVersion' tag in the XML.")
321
358
  except (requests.RequestException, ET.ParseError) as e:
322
- print(f" - Error fetching or parsing version info: {e}")
359
+ printText(f" - Error fetching or parsing version info: {e}")
323
360
 
324
- print(f" - Could not determine latest version. Falling back to {QPS_VERSION_FOR_DOWNLOAD}.")
361
+ printText(f" - Could not determine latest version. Falling back to {QPS_VERSION_FOR_DOWNLOAD}.")
325
362
  return QPS_VERSION_FOR_DOWNLOAD
326
363
 
327
364
 
328
365
  def is_download_url_valid(url):
329
366
  """Checks if the provided URL is valid using a HEAD request."""
330
367
  try:
331
- print(f"Checking URL: {url} ...")
368
+ printText(f"Checking URL: {url} ...")
332
369
  response = requests.head(url, timeout=10)
333
370
  response.raise_for_status()
334
- print(" - URL is valid.")
371
+ printText(" - URL is valid.")
335
372
  return True
336
373
  except requests.RequestException as e:
337
- print(f" - This URL is not valid: {e}")
374
+ printText(f" - This URL is not valid: {e}")
338
375
  return False
339
376
 
340
377
 
341
378
  if __name__ == "__main__":
342
- print("--- Running Component Check ---")
379
+ printText("--- Running Component Check ---")
343
380
  is_installed = find_qps()
344
381
  if is_installed:
345
- print("\nSuccess! All required components are present.")
382
+ printText("\nSuccess! All required components are present.")
346
383
  else:
347
- print("\n--- Script finished: Not all components could be found or installed. ---")
384
+ printText("\n--- Script finished: Not all components could be found or installed. ---")
quarchpy/qps/qpsFuncs.py CHANGED
@@ -148,6 +148,10 @@ def startLocalQps(keepQisRunning=False, args=[], timeout=30, startQPSMinimised=T
148
148
  else: # default to windows
149
149
  command = java_path + "\\win_amd64_jdk_jre\\bin\\java\" -jar qps.jar " + str(args)
150
150
 
151
+ if isQpsRunning():
152
+ logging.debug("QPS is already running. Not starting another instance.")
153
+ os.chdir(current_dir)
154
+ return
151
155
  if "-logging=ON" in str(args): #If logging to a terminal window is on then os.system should be used to keep a window open to view logging.
152
156
  if current_os in "Windows":
153
157
  process = subprocess.Popen(command,shell=True)
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: quarchpy
3
- Version: 2.2.15
3
+ Version: 2.2.16
4
4
  Summary: This packpage offers Python support for Quarch Technology modules.
5
5
  Author: Quarch Technology ltd
6
6
  Author-email: support@quarch.com
@@ -22,6 +22,15 @@ Requires-Dist: numpy
22
22
  Requires-Dist: pandas
23
23
  Requires-Dist: requests
24
24
  Requires-Dist: packaging
25
+ Dynamic: author
26
+ Dynamic: author-email
27
+ Dynamic: classifier
28
+ Dynamic: description
29
+ Dynamic: description-content-type
30
+ Dynamic: keywords
31
+ Dynamic: license
32
+ Dynamic: requires-dist
33
+ Dynamic: summary
25
34
 
26
35
  ====================
27
36
  Changelog (Quarchpy)
@@ -39,6 +48,10 @@ Change Log
39
48
  ----------
40
49
 
41
50
 
51
+ 2.2.16
52
+ ------
53
+ - New QPS 1.50 and QIS 1.52
54
+
42
55
  2.2.15
43
56
  ------
44
57
  - Bugfix for ">" appearing in qis output when streaming at max speed