diff --git a/migrations/009_item_extended_fields.sql b/migrations/010_item_extended_fields.sql similarity index 100% rename from migrations/009_item_extended_fields.sql rename to migrations/010_item_extended_fields.sql diff --git a/pkg/freecad/silo_commands.py b/pkg/freecad/silo_commands.py index 9e7c698..0e465dd 100644 --- a/pkg/freecad/silo_commands.py +++ b/pkg/freecad/silo_commands.py @@ -534,6 +534,17 @@ class SiloClient: except Exception: return False, None + def latest_file_revision(self, part_number: str) -> Optional[Dict]: + """Return the most recent revision that has a file attached, or None.""" + try: + revisions = self.get_revisions(part_number) + for rev in revisions: # revisions come newest-first from the API + if rev.get("file_key"): + return rev + return None + except Exception: + return None + def compare_revisions( self, part_number: str, from_rev: int, to_rev: int ) -> Dict[str, Any]: @@ -1757,9 +1768,11 @@ class Silo_Push: } def Activated(self): + from datetime import datetime, timezone + from PySide import QtGui - # Find unuploaded files + # Find files that need uploading (no server file, or local is newer) local_files = search_local_files() unuploaded = [] @@ -1767,9 +1780,30 @@ class Silo_Push: pn = lf["part_number"] try: _client.get_item(pn) # Check if in DB - has_file, _ = _client.has_file(pn) - if not has_file: + server_rev = _client.latest_file_revision(pn) + if not server_rev: + # No file on server at all unuploaded.append(lf) + else: + # Compare local mtime against server revision timestamp + try: + local_mtime = os.path.getmtime(lf["path"]) + server_time_str = server_rev.get("created_at", "") + if server_time_str: + server_dt = datetime.fromisoformat( + server_time_str.replace("Z", "+00:00") + ) + local_dt = datetime.fromtimestamp( + local_mtime, tz=timezone.utc + ) + if local_dt > server_dt: + unuploaded.append(lf) + else: + # Can't parse server time, assume needs upload + unuploaded.append(lf) + except Exception: + # On any comparison error, include it + unuploaded.append(lf) except Exception: pass # Not in DB, skip