Update dependencies and enhance CSV metadata handling

- Updated requirements.txt to specify minimum versions for PySide6, pyqtgraph, and numpy.
- Modified CSVFileMetadata class to include a new master_type attribute for improved metadata representation.
- Enhanced FileBrowser class to handle master_type in metadata saving and retrieval.
- Added a new method in FileBrowser for parsing CSV metadata, improving error handling and data extraction.
- Adjusted LocalSettingsModel to format code and change default reverseZWafer setting to False.
This commit is contained in:
Jack.Le
2026-05-05 10:00:00 -07:00
parent bbe7baea5b
commit f24dd89e8e
4 changed files with 55 additions and 6 deletions
+3 -1
View File
@@ -4,11 +4,12 @@ from datetime import datetime
# ===== CSV Metadata Model ===== # ===== CSV Metadata Model =====
class CSVFileMetadata: class CSVFileMetadata:
# ===== Lifecycle ===== # ===== Lifecycle =====
def __init__(self, wafer="", date="", chamber="", notes="", filename="", columns=0): def __init__(self, wafer="", date="", chamber="", notes="", master_type="", filename="", columns=0):
self.wafer = wafer self.wafer = wafer
self.date = date self.date = date
self.chamber = chamber self.chamber = chamber
self.notes = notes self.notes = notes
self.master_type = master_type
self.filename = filename self.filename = filename
self.columns = columns self.columns = columns
@@ -42,6 +43,7 @@ class CSVFileMetadata:
"date": self.string_date_format(), # Ensure we save as string "date": self.string_date_format(), # Ensure we save as string
"chamber": self.chamber, "chamber": self.chamber,
"notes": self.notes, "notes": self.notes,
"masterType": self.master_type,
} }
def string_date_format(self) -> str: def string_date_format(self) -> str:
+42 -1
View File
@@ -54,7 +54,7 @@ class FileBrowser(QObject):
self._refresh_files(show_empty_message=False) self._refresh_files(show_empty_message=False)
# ===== Metadata Persistence ===== # ===== Metadata Persistence =====
@Slot(str, str, str, str, str, bool) @Slot(str, str, str, str, str, bool, str)
def saveMetadata( def saveMetadata(
self, self,
file_path: str, file_path: str,
@@ -63,6 +63,7 @@ class FileBrowser(QObject):
chamber: str, chamber: str,
notes: str, notes: str,
selected: bool, selected: bool,
master_type: str = "",
) -> None: ) -> None:
csv_path = Path(file_path) csv_path = Path(file_path)
if not csv_path.exists(): if not csv_path.exists():
@@ -79,12 +80,14 @@ class FileBrowser(QObject):
row["chamber"] = chamber row["chamber"] = chamber
row["notes"] = notes row["notes"] = notes
row["selected"] = selected row["selected"] = selected
row["masterType"] = master_type
payload = { payload = {
"wafer": wafer, "wafer": wafer,
"date": date, "date": date,
"chamber": chamber, "chamber": chamber,
"notes": notes, "notes": notes,
"masterType": master_type,
} }
try: try:
@@ -103,6 +106,10 @@ class FileBrowser(QObject):
str(row.get("fileName", "")): bool(row.get("selected", False)) str(row.get("fileName", "")): bool(row.get("selected", False))
for row in self._files for row in self._files
} }
master_state = {
str(row.get("fileName", "")): row.get("masterType", "") or ""
for row in self._files
}
self._files = [] self._files = []
@@ -120,6 +127,7 @@ class FileBrowser(QObject):
"date": metadata.string_date_format(), "date": metadata.string_date_format(),
"chamber": metadata.chamber, "chamber": metadata.chamber,
"notes": metadata.notes, "notes": metadata.notes,
"masterType": master_state.get(str(csv_path), "") or metadata.master_type,
"fileName": str(csv_path), "fileName": str(csv_path),
"highlight": metadata.get_wafer_type() in {"A", "B", "C"}, "highlight": metadata.get_wafer_type() in {"A", "B", "C"},
} }
@@ -132,6 +140,7 @@ class FileBrowser(QObject):
"date": "", "date": "",
"chamber": "", "chamber": "",
"notes": "Unable to parse metadata", "notes": "Unable to parse metadata",
"masterType": master_state.get(str(csv_path), ""),
"fileName": str(csv_path), "fileName": str(csv_path),
"highlight": False, "highlight": False,
} }
@@ -152,6 +161,7 @@ class FileBrowser(QObject):
date=str(payload.get("date", "")), date=str(payload.get("date", "")),
chamber=str(payload.get("chamber", "")), chamber=str(payload.get("chamber", "")),
notes=str(payload.get("notes", "")), notes=str(payload.get("notes", "")),
master_type=str(payload.get("masterType", "")),
filename=str(csv_path), filename=str(csv_path),
) )
except Exception: except Exception:
@@ -222,6 +232,37 @@ class FileBrowser(QObject):
def _show_error(self, message: str) -> None: def _show_error(self, message: str) -> None:
QMessageBox.critical(None, "iSenseCloud", message) QMessageBox.critical(None, "iSenseCloud", message)
@Slot(str)
def showInfo(self, message: str) -> None:
self._show_info(message)
@Slot(str, result="QVariantMap")
def parseCsvMetadata(self, file_path: str) -> dict:
from pathlib import Path as _Path
csv_path = _Path(file_path)
if not csv_path.exists():
return {"success": False, "error": "File not found"}
parser_data, _ = self._parser.parse(file_path)
if parser_data is None:
return {"success": False, "error": "Failed to parse CSV"}
wafer = parser_data.serial or ""
date_text = ""
if parser_data.date != datetime.min:
date_text = CSVFileMetadata.format_date(parser_data.date)
columns = len(parser_data.csv_headers) if parser_data.csv_headers else 0
family_code = wafer[0].upper() if wafer else ""
return {
"success": True,
"wafer": wafer,
"date": date_text,
"columns": columns,
"familyCode": family_code,
}
def _show_info(self, message: str) -> None: def _show_info(self, message: str) -> None:
QMessageBox.information(None, "iSenseCloud", message) QMessageBox.information(None, "iSenseCloud", message)
+7 -3
View File
@@ -48,14 +48,16 @@ class LocalSettingsModel(QObject):
self._recompute_derived() self._recompute_derived()
def _resolve_data_dir(self) -> Path: def _resolve_data_dir(self) -> Path:
documents_dir = QStandardPaths.writableLocation(QStandardPaths.DocumentsLocation) documents_dir = QStandardPaths.writableLocation(
QStandardPaths.DocumentsLocation
)
base_dir = Path(documents_dir) if documents_dir else (Path.home() / "Documents") base_dir = Path(documents_dir) if documents_dir else (Path.home() / "Documents")
return base_dir / "isc_data" return base_dir / "isc_data"
def _new_defaults(self) -> dict[str, Any]: def _new_defaults(self) -> dict[str, Any]:
return { return {
"chamberId": "2", "chamberId": "2",
"reverseZWafer": True, "reverseZWafer": False,
"debugMode": False, "debugMode": False,
"waferReadTimeout": 120000, "waferReadTimeout": 120000,
"waferDetectTimeout": 5000, "waferDetectTimeout": 5000,
@@ -250,7 +252,9 @@ class LocalSettingsModel(QObject):
@Slot() @Slot()
def loadSettings(self) -> None: def loadSettings(self) -> None:
loaded = LocalSettings.read_settings(str(self._data_dir)) loaded = LocalSettings.read_settings(str(self._data_dir))
self._chamber_id = str(loaded.chamber_id).strip() or str(self._defaults["chamberId"]) self._chamber_id = str(loaded.chamber_id).strip() or str(
self._defaults["chamberId"]
)
self._reverse_z_wafer = bool(loaded.reverse_z_wafer) self._reverse_z_wafer = bool(loaded.reverse_z_wafer)
self._debug_mode = bool(loaded.debug) self._debug_mode = bool(loaded.debug)
self._wafer_read_timeout = int(loaded.wafer_read_timeout) self._wafer_read_timeout = int(loaded.wafer_read_timeout)
+3 -1
View File
@@ -1,2 +1,4 @@
# ===== Runtime Dependencies ===== # ===== Runtime Dependencies =====
PySide6 PySide6>=6.6.0
pyqtgraph>=0.13.0
numpy>=1.24.0