From a8b2500c0a5e3e2fc151858e81b19a5493733cbb Mon Sep 17 00:00:00 2001 From: Mucahit Bilal GOKER Date: Sun, 8 Dec 2024 21:23:00 +0300 Subject: [PATCH 1/2] first draft --- bpy_speckle/states/speckle_state.py | 3 -- bpy_speckle/ui/model_selection_dialog.py | 3 +- bpy_speckle/ui/version_selection_dialog.py | 44 ++++++++++++++------ bpy_speckle/utils/version_manager.py | 47 ++++++++++++++++++++++ 4 files changed, 81 insertions(+), 16 deletions(-) create mode 100644 bpy_speckle/utils/version_manager.py diff --git a/bpy_speckle/states/speckle_state.py b/bpy_speckle/states/speckle_state.py index 076dabb..a140f0b 100644 --- a/bpy_speckle/states/speckle_state.py +++ b/bpy_speckle/states/speckle_state.py @@ -2,12 +2,9 @@ from bpy.props import CollectionProperty, StringProperty, IntProperty, IntVectorProperty from ..ui.model_selection_dialog import speckle_model -from ..ui.version_selection_dialog import speckle_version from ..ui.model_card import speckle_model_card class SpeckleState(bpy.types.PropertyGroup): - models: CollectionProperty(type=speckle_model) - versions: CollectionProperty(type=speckle_version) ui_mode: StringProperty(name="UI Mode", default="NONE") model_cards: CollectionProperty(type=speckle_model_card) model_card_index: IntProperty(name="Model Card Index", default=0) diff --git a/bpy_speckle/ui/model_selection_dialog.py b/bpy_speckle/ui/model_selection_dialog.py index 95cdb8b..3c14295 100644 --- a/bpy_speckle/ui/model_selection_dialog.py +++ b/bpy_speckle/ui/model_selection_dialog.py @@ -96,7 +96,8 @@ def execute(self, context: Context) -> set[str]: project_name=self.project_name, project_id=self.project_id, model_name=selected_model.name, - model_id=selected_model.id) + model_id=selected_model.id, + account_id=context.window_manager.selected_account_id) return {'FINISHED'} def invoke(self, context: Context, event: Event) -> set[str]: diff --git a/bpy_speckle/ui/version_selection_dialog.py b/bpy_speckle/ui/version_selection_dialog.py index 013c393..a771edf 100644 --- a/bpy_speckle/ui/version_selection_dialog.py +++ b/bpy_speckle/ui/version_selection_dialog.py @@ -1,5 +1,6 @@ import bpy from .mouse_position_mixin import MousePositionMixin +from ..utils.version_manager import get_versions_for_model class speckle_version(bpy.types.PropertyGroup): """ @@ -60,14 +61,25 @@ class SPECKLE_OT_version_selection_dialog(MousePositionMixin, bpy.types.Operator default="" ) - versions = [ - ("648896", "Message 1", "12 day ago"), - ("658465", "Message 2", "15 days ago"), - ("154651", "Message 3", "20 days ago"), - ] + project_id: bpy.props.StringProperty( + name="Project ID", + description="ID of the selected project", + default="" + ) - version_index: bpy.props.IntProperty(name="Model Index", default=0) + model_id: bpy.props.StringProperty( + name="Model ID", + description="ID of the selected model", + default="" + ) + account_id: bpy.props.StringProperty( + name="Account ID", + description="ID of the current account", + default="" + ) + + version_index: bpy.props.IntProperty(name="Model Index", default=0) def execute(self, context): model_card = context.scene.speckle_state.model_cards.add() @@ -75,16 +87,22 @@ def execute(self, context): model_card.model_name = self.model_name model_card.is_publish = False # Store the selected version ID - selected_version = context.scene.speckle_state.versions[self.version_index] + selected_version = context.window_manager.speckle_versions[self.version_index] model_card.version_id = selected_version.id return {'FINISHED'} def invoke(self, context, event): # Clear existing versions - context.scene.speckle_state.versions.clear() - # Populate with new versions - for id, message, updated in self.versions: - version = context.scene.speckle_state.versions.add() + context.window_manager.speckle_versions.clear() + # Fetch and populate versions + versions = get_versions_for_model( + account_id=self.account_id, + project_id=self.project_id, + model_id=self.model_id, + search=self.search_query if self.search_query else None + ) + for id, message, updated in versions: + version = context.window_manager.speckle_versions.add() version.id = id version.message = message version.updated = updated @@ -98,11 +116,13 @@ def draw(self, context): layout.label(text=f"Project: {self.project_name}") layout.label(text=f"Model: {self.model_name}") # TODO: Add more UI elements here. + # TODO: Add more UI elements here. + # TODO: Add more UI elements here. # Search field row = layout.row(align=True) row.prop(self, "search_query", icon='VIEWZOOM', text="") # Versions UIList - layout.template_list("SPECKLE_UL_versions_list", "", context.scene.speckle_state, "versions", self, "version_index") + row.template_list("SPECKLE_UL_versions_list", "", context.window_manager, "speckle_versions", self, "version_index") layout.separator() diff --git a/bpy_speckle/utils/version_manager.py b/bpy_speckle/utils/version_manager.py new file mode 100644 index 0000000..62a299e --- /dev/null +++ b/bpy_speckle/utils/version_manager.py @@ -0,0 +1,47 @@ +from specklepy.api.client import SpeckleClient +from specklepy.api.credentials import get_local_accounts +from typing import List, Tuple, Optional +from .misc import format_relative_time +from specklepy.core.api.inputs.model_inputs import ModelVersionsFilter + +def get_versions_for_model(account_id: str, project_id: str, model_id: str, search: Optional[str] = None) -> List[Tuple[str, str, str]]: + """ + Fetch versions for a given model from the Speckle server. + + Args: + account_id: The ID of the Speckle account to fetch versions for + project_id: The ID of the project containing the model + model_id: The ID of the model to fetch versions from + search: Optional search string to filter versions + + Returns: + List of tuples containing (version_id, message, last_updated) + Returns empty list if any error occurs + """ + try: + # Validate inputs + if not account_id or not project_id or not model_id: + print(f"Error: Invalid inputs - account_id: {account_id}, project_id: {project_id}, model_id: {model_id}") + return [] + + # Get the account info + account = next((acc for acc in get_local_accounts() if acc.id == account_id), None) + if not account: + print(f"Error: Could not find account with ID: {account_id}") + return [] + + # Initialize the client + client = SpeckleClient(host=account.serverInfo.url) + # Authenticate + client.authenticate_with_account(account) + + filter = ModelVersionsFilter(search=search) + + # Get versions + versions = client.version.get_versions(project_id=project_id, model_id=model_id, limit=10, filter=filter) + + return [(version.id, version.message or "No message", format_relative_time(version.createdAt)) for version in versions] + + except Exception as e: + print(f"Error fetching versions: {str(e)}") + return [] \ No newline at end of file From 76aaf2fd413766e0782bff01fc9b722d0f92b317 Mon Sep 17 00:00:00 2001 From: Mucahit Bilal GOKER Date: Sun, 8 Dec 2024 21:54:06 +0300 Subject: [PATCH 2/2] it gets versions associated with the selected account --- bpy_speckle/ui/model_selection_dialog.py | 7 +-- bpy_speckle/ui/selection_filter_dialog.py | 12 +++++ bpy_speckle/ui/version_selection_dialog.py | 57 +++++++++++++--------- bpy_speckle/utils/version_manager.py | 4 +- 4 files changed, 49 insertions(+), 31 deletions(-) diff --git a/bpy_speckle/ui/model_selection_dialog.py b/bpy_speckle/ui/model_selection_dialog.py index 3c14295..c01c14c 100644 --- a/bpy_speckle/ui/model_selection_dialog.py +++ b/bpy_speckle/ui/model_selection_dialog.py @@ -96,20 +96,15 @@ def execute(self, context: Context) -> set[str]: project_name=self.project_name, project_id=self.project_id, model_name=selected_model.name, - model_id=selected_model.id, - account_id=context.window_manager.selected_account_id) + model_id=selected_model.id) return {'FINISHED'} def invoke(self, context: Context, event: Event) -> set[str]: - wm = context.window_manager # Ensure WindowManager has the projects collection if not hasattr(WindowManager, "speckle_models"): # Register the collection property WindowManager.speckle_models = bpy.props.CollectionProperty(type=speckle_model) - - # Clear existing models - wm.speckle_models.clear() # Update models list self.update_models_list(context) diff --git a/bpy_speckle/ui/selection_filter_dialog.py b/bpy_speckle/ui/selection_filter_dialog.py index 0094a49..76d565a 100644 --- a/bpy_speckle/ui/selection_filter_dialog.py +++ b/bpy_speckle/ui/selection_filter_dialog.py @@ -22,12 +22,24 @@ class SPECKLE_OT_selection_filter_dialog(MousePositionMixin, bpy.types.Operator) default="" ) + project_id: bpy.props.StringProperty( + name="Project ID", + description="ID of the selected project", + default="" + ) + model_name: bpy.props.StringProperty( name="Model Name", description="Name of the selected model", default="" ) + model_id: bpy.props.StringProperty( + name="Model ID", + description="ID of the selected model", + default="" + ) + def execute(self, context): model_card = context.scene.speckle_state.model_cards.add() model_card.project_name = self.project_name diff --git a/bpy_speckle/ui/version_selection_dialog.py b/bpy_speckle/ui/version_selection_dialog.py index a771edf..8d6cb42 100644 --- a/bpy_speckle/ui/version_selection_dialog.py +++ b/bpy_speckle/ui/version_selection_dialog.py @@ -1,4 +1,5 @@ import bpy +from bpy.types import WindowManager from .mouse_position_mixin import MousePositionMixin from ..utils.version_manager import get_versions_for_model @@ -73,14 +74,31 @@ class SPECKLE_OT_version_selection_dialog(MousePositionMixin, bpy.types.Operator default="" ) - account_id: bpy.props.StringProperty( - name="Account ID", - description="ID of the current account", - default="" - ) - version_index: bpy.props.IntProperty(name="Model Index", default=0) + def update_versions_list(self, context): + wm = context.window_manager + # Clear existing versions + wm.speckle_versions.clear() + + # Get versions for the selected model + search = self.search_query if self.search_query.strip() else None + versions = get_versions_for_model( + account_id=wm.selected_account_id, + project_id=self.project_id, + model_id=self.model_id, + search=search + ) + + # Populate versions list + for id, message, updated in versions: + version = wm.speckle_versions.add() + version.id = id + version.message = message + version.updated = updated + + return None + def execute(self, context): model_card = context.scene.speckle_state.model_cards.add() model_card.project_name = self.project_name @@ -92,23 +110,18 @@ def execute(self, context): return {'FINISHED'} def invoke(self, context, event): - # Clear existing versions - context.window_manager.speckle_versions.clear() - # Fetch and populate versions - versions = get_versions_for_model( - account_id=self.account_id, - project_id=self.project_id, - model_id=self.model_id, - search=self.search_query if self.search_query else None - ) - for id, message, updated in versions: - version = context.window_manager.speckle_versions.add() - version.id = id - version.message = message - version.updated = updated + + # Ensure WindowManager has the versions collection + if not hasattr(WindowManager, "speckle_versions"): + # Register the collection property + WindowManager.speckle_versions = bpy.props.CollectionProperty(type=speckle_version) + + # Update versions list + self.update_versions_list(context) # Initialize mouse position self.init_mouse_position(context, event) + return context.window_manager.invoke_props_dialog(self) def draw(self, context): @@ -116,13 +129,11 @@ def draw(self, context): layout.label(text=f"Project: {self.project_name}") layout.label(text=f"Model: {self.model_name}") # TODO: Add more UI elements here. - # TODO: Add more UI elements here. - # TODO: Add more UI elements here. # Search field row = layout.row(align=True) row.prop(self, "search_query", icon='VIEWZOOM', text="") # Versions UIList - row.template_list("SPECKLE_UL_versions_list", "", context.window_manager, "speckle_versions", self, "version_index") + layout.template_list("SPECKLE_UL_versions_list", "", context.window_manager, "speckle_versions", self, "version_index") layout.separator() diff --git a/bpy_speckle/utils/version_manager.py b/bpy_speckle/utils/version_manager.py index 62a299e..23c0898 100644 --- a/bpy_speckle/utils/version_manager.py +++ b/bpy_speckle/utils/version_manager.py @@ -35,10 +35,10 @@ def get_versions_for_model(account_id: str, project_id: str, model_id: str, sear # Authenticate client.authenticate_with_account(account) - filter = ModelVersionsFilter(search=search) + filter = ModelVersionsFilter(search=search, priorityIds=[]) # Get versions - versions = client.version.get_versions(project_id=project_id, model_id=model_id, limit=10, filter=filter) + versions = client.version.get_versions(project_id=project_id, model_id=model_id, limit=10, filter=filter).items return [(version.id, version.message or "No message", format_relative_time(version.createdAt)) for version in versions]