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:
@@ -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
@@ -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)
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -1,2 +1,4 @@
|
|||||||
# ===== Runtime Dependencies =====
|
# ===== Runtime Dependencies =====
|
||||||
PySide6
|
PySide6>=6.6.0
|
||||||
|
pyqtgraph>=0.13.0
|
||||||
|
numpy>=1.24.0
|
||||||
|
|||||||
Reference in New Issue
Block a user