Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bilal/cnx 892 replace placeholder version dialog #218

Merged
merged 3 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions bpy_speckle/states/speckle_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 0 additions & 4 deletions bpy_speckle/ui/model_selection_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,11 @@ def execute(self, context: Context) -> set[str]:
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)
Expand Down
12 changes: 12 additions & 0 deletions bpy_speckle/ui/selection_filter_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
61 changes: 46 additions & 15 deletions bpy_speckle/ui/version_selection_dialog.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import bpy
from bpy.types import WindowManager
from .mouse_position_mixin import MousePositionMixin
from ..utils.version_manager import get_versions_for_model

class speckle_version(bpy.types.PropertyGroup):
"""
Expand Down Expand Up @@ -60,37 +62,66 @@ 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=""
)

model_id: bpy.props.StringProperty(
name="Model ID",
description="ID of the selected model",
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
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()
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):
Expand All @@ -102,7 +133,7 @@ def draw(self, context):
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")
layout.template_list("SPECKLE_UL_versions_list", "", context.window_manager, "speckle_versions", self, "version_index")

layout.separator()

Expand Down
47 changes: 47 additions & 0 deletions bpy_speckle/utils/version_manager.py
Original file line number Diff line number Diff line change
@@ -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, priorityIds=[])

# Get versions
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]

except Exception as e:
print(f"Error fetching versions: {str(e)}")
return []