mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 15:08:51 +00:00
Rename ifcviewer-autodesk connector to bonsaiviewer-autodesk
Follows the host viewer's rename to Bonsai Viewer: directory, Python package, entry point, PyInstaller spec, keyring service, and on-disk config/cache paths all use the bonsaiviewer-autodesk name. CI workflow filename and path filters updated to match. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+7
-7
@@ -1,15 +1,15 @@
|
|||||||
name: Build IfcViewer Autodesk Connector
|
name: Build Bonsai Viewer Autodesk Connector
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
paths:
|
paths:
|
||||||
- 'src/ifcviewer-autodesk/**'
|
- 'src/bonsaiviewer-autodesk/**'
|
||||||
- '.github/workflows/build-ifcviewer-autodesk.yml'
|
- '.github/workflows/build-bonsaiviewer-autodesk.yml'
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- 'src/ifcviewer-autodesk/**'
|
- 'src/bonsaiviewer-autodesk/**'
|
||||||
- '.github/workflows/build-ifcviewer-autodesk.yml'
|
- '.github/workflows/build-bonsaiviewer-autodesk.yml'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -39,7 +39,7 @@ jobs:
|
|||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
working-directory: src/ifcviewer-autodesk
|
working-directory: src/bonsaiviewer-autodesk
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
@@ -64,5 +64,5 @@ jobs:
|
|||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: autodesk-${{ matrix.os_label }}-${{ matrix.arch }}
|
name: autodesk-${{ matrix.os_label }}-${{ matrix.arch }}
|
||||||
path: src/ifcviewer-autodesk/dist/autodesk-${{ matrix.os_label }}-${{ matrix.arch }}.zip
|
path: src/bonsaiviewer-autodesk/dist/autodesk-${{ matrix.os_label }}-${{ matrix.arch }}.zip
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
+3
-3
@@ -129,6 +129,6 @@ src/ifcopenshell-python/ifcopenshell/express/*.exp.cache.dat
|
|||||||
*.py.tmp*
|
*.py.tmp*
|
||||||
*.json.tmp*
|
*.json.tmp*
|
||||||
|
|
||||||
# ifcviewer-autodesk connector build artifacts
|
# bonsaiviewer-autodesk connector build artifacts
|
||||||
/src/ifcviewer-autodesk/build/
|
/src/bonsaiviewer-autodesk/build/
|
||||||
/src/ifcviewer-autodesk/dist/
|
/src/bonsaiviewer-autodesk/dist/
|
||||||
|
|||||||
+56
-56
@@ -1,13 +1,13 @@
|
|||||||
# IfcViewer cloud connectors
|
# Bonsai Viewer cloud connectors
|
||||||
|
|
||||||
IfcViewer will have the capability to load and save projects and models from a
|
Bonsai Viewer will have the capability to load and save projects and models from a
|
||||||
cloud platform. Later on, there will be other resources stored on cloud
|
cloud platform. Later on, there will be other resources stored on cloud
|
||||||
platforms too, such as issues, clash results, and so on, but this behaviour is
|
platforms too, such as issues, clash results, and so on, but this behaviour is
|
||||||
not currently designed.
|
not currently designed.
|
||||||
|
|
||||||
Due to the variety of cloud platforms, the IfcViewer itself will depend on
|
Due to the variety of cloud platforms, the Bonsai Viewer itself will depend on
|
||||||
a "connector" to integrate with each platform. The connector is a separate
|
a "connector" to integrate with each platform. The connector is a separate
|
||||||
application which will communicate to and from the IfcViewer.
|
application which will communicate to and from the Bonsai Viewer.
|
||||||
|
|
||||||
The following types of resources may be managed with a connector:
|
The following types of resources may be managed with a connector:
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ The following types of resources may be managed with a connector:
|
|||||||
|
|
||||||
## Communication protocol
|
## Communication protocol
|
||||||
|
|
||||||
The IfcViewer launches one connector process per session, on first use, and
|
The Bonsai Viewer launches one connector process per session, on first use, and
|
||||||
keeps it alive for the duration of the session. This allows the connector to
|
keeps it alive for the duration of the session. This allows the connector to
|
||||||
maintain authentication tokens, browse state, in-flight downloads, and caches
|
maintain authentication tokens, browse state, in-flight downloads, and caches
|
||||||
in memory across calls without re-authenticating on every request.
|
in memory across calls without re-authenticating on every request.
|
||||||
@@ -28,18 +28,18 @@ Communication is over stdio using newline-delimited JSON-RPC 2.0:
|
|||||||
- Requests and responses are single-line JSON objects on the connector's
|
- Requests and responses are single-line JSON objects on the connector's
|
||||||
stdin/stdout. Each message is terminated by a single `\n`.
|
stdin/stdout. Each message is terminated by a single `\n`.
|
||||||
- The connector must not emit literal newlines inside a JSON message.
|
- The connector must not emit literal newlines inside a JSON message.
|
||||||
- The connector may write arbitrary diagnostic output to stderr; the IfcViewer
|
- The connector may write arbitrary diagnostic output to stderr; the Bonsai Viewer
|
||||||
will not parse it.
|
will not parse it.
|
||||||
|
|
||||||
The IfcViewer shuts a connector down by closing its stdin. The connector should
|
The Bonsai Viewer shuts a connector down by closing its stdin. The connector should
|
||||||
exit cleanly. If it does not exit within a few seconds, the IfcViewer will
|
exit cleanly. If it does not exit within a few seconds, the Bonsai Viewer will
|
||||||
terminate it.
|
terminate it.
|
||||||
|
|
||||||
## Connector scope
|
## Connector scope
|
||||||
|
|
||||||
The IfcViewer has minimal knowledge about connectors. IfcViewer only knows how
|
The Bonsai Viewer has minimal knowledge about connectors. Bonsai Viewer only knows how
|
||||||
to work with local files. If it detects that a project or model is not local,
|
to work with local files. If it detects that a project or model is not local,
|
||||||
it will invoke a connector. The connector's job is to resolve the IfcViewer's
|
it will invoke a connector. The connector's job is to resolve the Bonsai Viewer's
|
||||||
request back into a local file and cloud metadata. The connector must not
|
request back into a local file and cloud metadata. The connector must not
|
||||||
modify the file in any way.
|
modify the file in any way.
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ This makes connectors very flexible.
|
|||||||
A single project may have different resources coming from different connectors.
|
A single project may have different resources coming from different connectors.
|
||||||
For example, some models might be on one platform, and some projects hosted on
|
For example, some models might be on one platform, and some projects hosted on
|
||||||
another platform. The permissions regarding model access can be quite granular
|
another platform. The permissions regarding model access can be quite granular
|
||||||
and therefore managed by the platform, and not IfcViewer.
|
and therefore managed by the platform, and not Bonsai Viewer.
|
||||||
|
|
||||||
When a connector returns a local file, that file is required to be the sole
|
When a connector returns a local file, that file is required to be the sole
|
||||||
child in its directory. This is because there may be adjacent temporary files,
|
child in its directory. This is because there may be adjacent temporary files,
|
||||||
@@ -140,9 +140,9 @@ Note that cloud metadata (filename, cloud ID, revision, date modified, etc) is
|
|||||||
not specified nor stored in the .ifcfed. This is to be returned by the
|
not specified nor stored in the .ifcfed. This is to be returned by the
|
||||||
connector when requested.
|
connector when requested.
|
||||||
|
|
||||||
The IfcViewer will display all returned cloud metadata as simple text strings.
|
The Bonsai Viewer will display all returned cloud metadata as simple text strings.
|
||||||
However some keys are treated specially and shown in more places in the
|
However some keys are treated specially and shown in more places in the
|
||||||
IfcViewer UI for convenience:
|
Bonsai Viewer UI for convenience:
|
||||||
|
|
||||||
- author
|
- author
|
||||||
- revision
|
- revision
|
||||||
@@ -157,7 +157,7 @@ perfectly acceptable to give the user choice on whether to download all or some
|
|||||||
models, or use cache (even if outdated). The user can always reopen the project
|
models, or use cache (even if outdated). The user can always reopen the project
|
||||||
later.
|
later.
|
||||||
|
|
||||||
1. The user presses a button in the IfcViewer UI that says "Open from Cloud"
|
1. The user presses a button in the Bonsai Viewer UI that says "Open from Cloud"
|
||||||
2. The user chooses a connector.
|
2. The user chooses a connector.
|
||||||
3. The `pull_ifcfed_interactive` method is sent to the connector.
|
3. The `pull_ifcfed_interactive` method is sent to the connector.
|
||||||
```json
|
```json
|
||||||
@@ -171,8 +171,8 @@ later.
|
|||||||
```json
|
```json
|
||||||
{ "jsonrpc": "2.0", "id": "0", "result": { "path": "/path/to/project/file.ifcfed" } }
|
{ "jsonrpc": "2.0", "id": "0", "result": { "path": "/path/to/project/file.ifcfed" } }
|
||||||
```
|
```
|
||||||
5. The IfcViewer loads the `path`. This constitutes a fresh session.
|
5. The Bonsai Viewer loads the `path`. This constitutes a fresh session.
|
||||||
6. The IfcViewer calls `pull_models`:
|
6. The Bonsai Viewer calls `pull_models`:
|
||||||
```json
|
```json
|
||||||
{ "jsonrpc": "2.0", "id": "1", "method": "pull_models", "params": [
|
{ "jsonrpc": "2.0", "id": "1", "method": "pull_models", "params": [
|
||||||
{ "display_name": ..., "id": ..., "source": ..., },
|
{ "display_name": ..., "id": ..., "source": ..., },
|
||||||
@@ -185,7 +185,7 @@ later.
|
|||||||
{ "jsonrpc": "2.0", "id": "1", "result": [
|
{ "jsonrpc": "2.0", "id": "1", "result": [
|
||||||
{ "path": "/path/to/foo.ifc" },
|
{ "path": "/path/to/foo.ifc" },
|
||||||
{
|
{
|
||||||
"path": "/path/to/model.ifc", # Used to load the model in IfcViewer
|
"path": "/path/to/model.ifc", # Used to load the model in Bonsai Viewer
|
||||||
"metadata": { "revision": "B", "date": "2nd Oct 2025" ... }, # Optional, used to display stats
|
"metadata": { "revision": "B", "date": "2nd Oct 2025" ... }, # Optional, used to display stats
|
||||||
},
|
},
|
||||||
null, # If skipped, error, etc
|
null, # If skipped, error, etc
|
||||||
@@ -193,8 +193,8 @@ later.
|
|||||||
...
|
...
|
||||||
] }
|
] }
|
||||||
```
|
```
|
||||||
8. The IfcViewer may call another connector with more models to be downloaded.
|
8. The Bonsai Viewer may call another connector with more models to be downloaded.
|
||||||
9. The IfcViewer will load the downloaded models as regular files. Typically this will also result in the IfcViewer reading / writing a cache (e.g. .ifcview) alongside this file, but it is not expected that the connector will know or care about this.
|
9. The Bonsai Viewer will load the downloaded models as regular files. Typically this will also result in the Bonsai Viewer reading / writing a cache (e.g. .ifcview) alongside this file, but it is not expected that the connector will know or care about this.
|
||||||
|
|
||||||
## Sync cloud to local
|
## Sync cloud to local
|
||||||
|
|
||||||
@@ -205,8 +205,8 @@ the project has any cloud resources: a `.ifcfed.manifest` adjacent to the
|
|||||||
.ifcfed-refresh phase and the model-refresh phase are independent — only the
|
.ifcfed-refresh phase and the model-refresh phase are independent — only the
|
||||||
first requires a manifest.
|
first requires a manifest.
|
||||||
|
|
||||||
1. The user presses a button in the IfcViewer UI that says "Sync Cloud to Local"
|
1. The user presses a button in the Bonsai Viewer UI that says "Sync Cloud to Local"
|
||||||
2. IfcViewer reads the .ifcfed.manifest and invokes the relevant connector with the manifest data with the `pull_ifcfed` method:
|
2. Bonsai Viewer reads the .ifcfed.manifest and invokes the relevant connector with the manifest data with the `pull_ifcfed` method:
|
||||||
```json
|
```json
|
||||||
{ "jsonrpc": "2.0", "id": "0", "method": "pull_ifcfed", "params": {
|
{ "jsonrpc": "2.0", "id": "0", "method": "pull_ifcfed", "params": {
|
||||||
"connector": "mycompany", "version": "2", "url": ...
|
"connector": "mycompany", "version": "2", "url": ...
|
||||||
@@ -223,16 +223,16 @@ first requires a manifest.
|
|||||||
4. Continue with step 5 of the "Open from cloud" workflow.
|
4. Continue with step 5 of the "Open from cloud" workflow.
|
||||||
|
|
||||||
If no `.ifcfed.manifest` is present, steps 2–4 are skipped. The .ifcfed on
|
If no `.ifcfed.manifest` is present, steps 2–4 are skipped. The .ifcfed on
|
||||||
disk is used as-is, and the IfcViewer continues from step 6 of the
|
disk is used as-is, and the Bonsai Viewer continues from step 6 of the
|
||||||
"Open from cloud" workflow (calling `pull_models` for any cloud-sourced models
|
"Open from cloud" workflow (calling `pull_models` for any cloud-sourced models
|
||||||
referenced in the .ifcfed).
|
referenced in the .ifcfed).
|
||||||
|
|
||||||
Additionally, if the .ifcfed returned in step 3 is unchanged from the one
|
Additionally, if the .ifcfed returned in step 3 is unchanged from the one
|
||||||
already loaded (e.g. the connector served a cached copy because the cloud
|
already loaded (e.g. the connector served a cached copy because the cloud
|
||||||
revision matched), the IfcViewer skips step 5 as well and continues from
|
revision matched), the Bonsai Viewer skips step 5 as well and continues from
|
||||||
step 6, preserving the current session rather than forcing an unnecessary
|
step 6, preserving the current session rather than forcing an unnecessary
|
||||||
fresh one. How "unchanged" is determined (byte equality, hash, mtime, etc.)
|
fresh one. How "unchanged" is determined (byte equality, hash, mtime, etc.)
|
||||||
is left to the IfcViewer.
|
is left to the Bonsai Viewer.
|
||||||
|
|
||||||
## Save as to cloud
|
## Save as to cloud
|
||||||
|
|
||||||
@@ -240,7 +240,7 @@ This pushes a .ifcfed to a fresh location on a cloud platform, chosen by the
|
|||||||
user. It is the "Save As" equivalent and is the only way to first establish a
|
user. It is the "Save As" equivalent and is the only way to first establish a
|
||||||
cloud location for a project that does not yet have a `.ifcfed.manifest`.
|
cloud location for a project that does not yet have a `.ifcfed.manifest`.
|
||||||
|
|
||||||
1. The user presses a button in the IfcViewer UI that says "Save As to Cloud"
|
1. The user presses a button in the Bonsai Viewer UI that says "Save As to Cloud"
|
||||||
2. The user chooses a connector.
|
2. The user chooses a connector.
|
||||||
3. The `push_ifcfed_interactive` method is called with the path to the .ifcfed. The connector should treat this as a temporary .ifcfed file, as the real project may or may not be actually saved on disk.
|
3. The `push_ifcfed_interactive` method is called with the path to the .ifcfed. The connector should treat this as a temporary .ifcfed file, as the real project may or may not be actually saved on disk.
|
||||||
```json
|
```json
|
||||||
@@ -254,7 +254,7 @@ cloud location for a project that does not yet have a `.ifcfed.manifest`.
|
|||||||
```json
|
```json
|
||||||
{ "jsonrpc": "2.0", "id": "0", "result": { "path": "/path/to/project/file.ifcfed" } }
|
{ "jsonrpc": "2.0", "id": "0", "result": { "path": "/path/to/project/file.ifcfed" } }
|
||||||
```
|
```
|
||||||
5. The IfcViewer "repoints" to the returned path. It is not necessary to do a full reload as no "changes" are made.
|
5. The Bonsai Viewer "repoints" to the returned path. It is not necessary to do a full reload as no "changes" are made.
|
||||||
|
|
||||||
## Save to cloud
|
## Save to cloud
|
||||||
|
|
||||||
@@ -262,8 +262,8 @@ This pushes a .ifcfed back to the cloud location it originally came from,
|
|||||||
without prompting the user. It is the "Save" equivalent and is only available
|
without prompting the user. It is the "Save" equivalent and is only available
|
||||||
when there is a `.ifcfed.manifest` adjacent to the project.
|
when there is a `.ifcfed.manifest` adjacent to the project.
|
||||||
|
|
||||||
1. The user presses a button in the IfcViewer UI that says "Save to Cloud"
|
1. The user presses a button in the Bonsai Viewer UI that says "Save to Cloud"
|
||||||
2. IfcViewer reads the .ifcfed.manifest and invokes the relevant connector with the `push_ifcfed` method, passing both the local path and the manifest data:
|
2. Bonsai Viewer reads the .ifcfed.manifest and invokes the relevant connector with the `push_ifcfed` method, passing both the local path and the manifest data:
|
||||||
```json
|
```json
|
||||||
{ "jsonrpc": "2.0", "id": "0", "method": "push_ifcfed", "params": {
|
{ "jsonrpc": "2.0", "id": "0", "method": "push_ifcfed", "params": {
|
||||||
"path": "/tmp/path/to/project.ifcfed",
|
"path": "/tmp/path/to/project.ifcfed",
|
||||||
@@ -278,18 +278,18 @@ when there is a `.ifcfed.manifest` adjacent to the project.
|
|||||||
```json
|
```json
|
||||||
{ "jsonrpc": "2.0", "id": "0", "result": { "path": "/path/to/project/file.ifcfed" } }
|
{ "jsonrpc": "2.0", "id": "0", "result": { "path": "/path/to/project/file.ifcfed" } }
|
||||||
```
|
```
|
||||||
4. The IfcViewer "repoints" to the returned path. It is not necessary to do a full reload as no "changes" are made.
|
4. The Bonsai Viewer "repoints" to the returned path. It is not necessary to do a full reload as no "changes" are made.
|
||||||
|
|
||||||
Conflict resolution for non-interactive push methods (the cloud copy moved on
|
Conflict resolution for non-interactive push methods (the cloud copy moved on
|
||||||
since the manifest or source was captured, the user lacks write permission,
|
since the manifest or source was captured, the user lacks write permission,
|
||||||
revision-pinning policies, etc.) is entirely the connector's responsibility.
|
revision-pinning policies, etc.) is entirely the connector's responsibility.
|
||||||
The connector may silently overwrite, prompt the user, refuse with a JSON-RPC
|
The connector may silently overwrite, prompt the user, refuse with a JSON-RPC
|
||||||
error, or anything in between. The IfcViewer expresses no opinion. This rule
|
error, or anything in between. The Bonsai Viewer expresses no opinion. This rule
|
||||||
also applies to `push_model` below.
|
also applies to `push_model` below.
|
||||||
|
|
||||||
## Add model from cloud
|
## Add model from cloud
|
||||||
|
|
||||||
1. The user presses a button in the IfcViewer UI that says "Add model from cloud"
|
1. The user presses a button in the Bonsai Viewer UI that says "Add model from cloud"
|
||||||
2. The user chooses a connector.
|
2. The user chooses a connector.
|
||||||
3. The `pull_models_interactive` method is sent to the connector.
|
3. The `pull_models_interactive` method is sent to the connector.
|
||||||
```json
|
```json
|
||||||
@@ -305,16 +305,16 @@ also applies to `push_model` below.
|
|||||||
{
|
{
|
||||||
"display_name": "bar.ifc", # Stored in .ifcfed
|
"display_name": "bar.ifc", # Stored in .ifcfed
|
||||||
"source": { "connector": "autodesk", ... }, # Stored in .ifcfed
|
"source": { "connector": "autodesk", ... }, # Stored in .ifcfed
|
||||||
"path": "/path/to/model.ifc", # Used to load the model in IfcViewer
|
"path": "/path/to/model.ifc", # Used to load the model in Bonsai Viewer
|
||||||
"metadata": { "revision": "B", "date": "2nd Oct 2025" ... }, # Optional, used to display stats
|
"metadata": { "revision": "B", "date": "2nd Oct 2025" ... }, # Optional, used to display stats
|
||||||
},
|
},
|
||||||
{ ... },
|
{ ... },
|
||||||
...
|
...
|
||||||
] }
|
] }
|
||||||
```
|
```
|
||||||
5. The IfcViewer updates the .ifcfed models section with new models using the
|
5. The Bonsai Viewer updates the .ifcfed models section with new models using the
|
||||||
"source" and "display\_name" from the provided data. The models are
|
"source" and "display\_name" from the provided data. The models are
|
||||||
immediately loaded from the "path", and the IfcViewer stores the "metadata"
|
immediately loaded from the "path", and the Bonsai Viewer stores the "metadata"
|
||||||
for display. The path and metadata is never stored in the .ifcfed.
|
for display. The path and metadata is never stored in the .ifcfed.
|
||||||
|
|
||||||
## Save model as to cloud
|
## Save model as to cloud
|
||||||
@@ -323,7 +323,7 @@ This pushes a model to a fresh location on a cloud platform, chosen by the
|
|||||||
user. It is the "Save As" equivalent and is the only way to first establish a
|
user. It is the "Save As" equivalent and is the only way to first establish a
|
||||||
cloud `source` for a model whose current source is `local`.
|
cloud `source` for a model whose current source is `local`.
|
||||||
|
|
||||||
1. The user presses a button in the IfcViewer UI that says "Save Model As to Cloud"
|
1. The user presses a button in the Bonsai Viewer UI that says "Save Model As to Cloud"
|
||||||
2. The user chooses a connector.
|
2. The user chooses a connector.
|
||||||
3. The `push_model_interactive` method is sent to the connector with a path to the model to be uploaded (typically a file, but RocksDB databases can be a folder).
|
3. The `push_model_interactive` method is sent to the connector with a path to the model to be uploaded (typically a file, but RocksDB databases can be a folder).
|
||||||
```json
|
```json
|
||||||
@@ -342,7 +342,7 @@ cloud `source` for a model whose current source is `local`.
|
|||||||
"metadata": { "revision": "B", "date": "2nd Oct 2025" ... }, # Optional, used to display stats
|
"metadata": { "revision": "B", "date": "2nd Oct 2025" ... }, # Optional, used to display stats
|
||||||
} }
|
} }
|
||||||
```
|
```
|
||||||
5. The IfcViewer updates the .ifcfed models section with the new model metadata from the provided data.
|
5. The Bonsai Viewer updates the .ifcfed models section with the new model metadata from the provided data.
|
||||||
|
|
||||||
## Save model to cloud
|
## Save model to cloud
|
||||||
|
|
||||||
@@ -351,8 +351,8 @@ without prompting the user. It is the "Save" equivalent and is only available
|
|||||||
for models whose .ifcfed `source` already points at a cloud connector (i.e.
|
for models whose .ifcfed `source` already points at a cloud connector (i.e.
|
||||||
anything other than `local`).
|
anything other than `local`).
|
||||||
|
|
||||||
1. The user presses a button in the IfcViewer UI that says "Save Model to Cloud"
|
1. The user presses a button in the Bonsai Viewer UI that says "Save Model to Cloud"
|
||||||
2. IfcViewer invokes the connector named in the model's `source` with the `push_model` method, passing both the local path and the existing `source` object verbatim:
|
2. Bonsai Viewer invokes the connector named in the model's `source` with the `push_model` method, passing both the local path and the existing `source` object verbatim:
|
||||||
```json
|
```json
|
||||||
{ "jsonrpc": "2.0", "id": "0", "method": "push_model", "params": {
|
{ "jsonrpc": "2.0", "id": "0", "method": "push_model", "params": {
|
||||||
"path": "/tmp/path/to/model.ifc",
|
"path": "/tmp/path/to/model.ifc",
|
||||||
@@ -370,17 +370,17 @@ anything other than `local`).
|
|||||||
"metadata": { "revision": "C", "date": "19th May 2026" ... }, # Optional, used to display stats
|
"metadata": { "revision": "C", "date": "19th May 2026" ... }, # Optional, used to display stats
|
||||||
} }
|
} }
|
||||||
```
|
```
|
||||||
4. The IfcViewer replaces the model's `source` in the .ifcfed and refreshes the stored metadata for display.
|
4. The Bonsai Viewer replaces the model's `source` in the .ifcfed and refreshes the stored metadata for display.
|
||||||
|
|
||||||
## Connector settings (optional)
|
## Connector settings (optional)
|
||||||
|
|
||||||
A connector MAY implement an `open_settings` method that the IfcViewer invokes
|
A connector MAY implement an `open_settings` method that the Bonsai Viewer invokes
|
||||||
when the user clicks the connector's settings entry (e.g. a gear icon next to
|
when the user clicks the connector's settings entry (e.g. a gear icon next to
|
||||||
the connector name). The connector is responsible for the entire settings UI:
|
the connector name). The connector is responsible for the entire settings UI:
|
||||||
credentials, sign-out, default folders, anything connector-specific.
|
credentials, sign-out, default folders, anything connector-specific.
|
||||||
|
|
||||||
1. The user clicks the connector's settings entry in the IfcViewer UI.
|
1. The user clicks the connector's settings entry in the Bonsai Viewer UI.
|
||||||
2. The IfcViewer sends `open_settings`:
|
2. The Bonsai Viewer sends `open_settings`:
|
||||||
```json
|
```json
|
||||||
{ "jsonrpc": "2.0", "id": "0", "method": "open_settings" }
|
{ "jsonrpc": "2.0", "id": "0", "method": "open_settings" }
|
||||||
```
|
```
|
||||||
@@ -391,7 +391,7 @@ credentials, sign-out, default folders, anything connector-specific.
|
|||||||
```
|
```
|
||||||
|
|
||||||
If the connector returns a JSON-RPC `Method not found` error (code `-32601`),
|
If the connector returns a JSON-RPC `Method not found` error (code `-32601`),
|
||||||
the IfcViewer should treat that connector as having no settings and hide its
|
the Bonsai Viewer should treat that connector as having no settings and hide its
|
||||||
settings entry. There is no other discovery mechanism — the viewer probes by
|
settings entry. There is no other discovery mechanism — the viewer probes by
|
||||||
calling the method when needed.
|
calling the method when needed.
|
||||||
|
|
||||||
@@ -408,22 +408,22 @@ optional fields (for example a fresh display label for the connector).
|
|||||||
### Error Response
|
### Error Response
|
||||||
|
|
||||||
The connector owns all user-facing error handling: dialogs, retry prompts,
|
The connector owns all user-facing error handling: dialogs, retry prompts,
|
||||||
re-auth flows, logs. The IfcViewer does not interpret or display connector
|
re-auth flows, logs. The Bonsai Viewer does not interpret or display connector
|
||||||
errors directly.
|
errors directly.
|
||||||
|
|
||||||
The protocol expresses only two outcomes:
|
The protocol expresses only two outcomes:
|
||||||
|
|
||||||
- **Per-item soft failure** (one model in a batch failed, others succeeded):
|
- **Per-item soft failure** (one model in a batch failed, others succeeded):
|
||||||
the connector returns `null` in that slot of the result array. The IfcViewer
|
the connector returns `null` in that slot of the result array. The Bonsai Viewer
|
||||||
skips it and continues.
|
skips it and continues.
|
||||||
- **Whole-call hard failure** (the connector cannot service the request at
|
- **Whole-call hard failure** (the connector cannot service the request at
|
||||||
all): the connector returns a JSON-RPC error object. The IfcViewer aborts
|
all): the connector returns a JSON-RPC error object. The Bonsai Viewer aborts
|
||||||
the operation. The `error.message` may be logged by the IfcViewer for
|
the operation. The `error.message` may be logged by the Bonsai Viewer for
|
||||||
diagnostics, but is not shown to the user — the connector is expected to
|
diagnostics, but is not shown to the user — the connector is expected to
|
||||||
have already surfaced the problem in its own UI.
|
have already surfaced the problem in its own UI.
|
||||||
|
|
||||||
Diagnostic detail (stack traces, codes, retry context) should be written to
|
Diagnostic detail (stack traces, codes, retry context) should be written to
|
||||||
stderr, which the IfcViewer captures for logs.
|
stderr, which the Bonsai Viewer captures for logs.
|
||||||
|
|
||||||
## Permissions
|
## Permissions
|
||||||
|
|
||||||
@@ -438,7 +438,7 @@ The viewer will tolerate partial failure and report skipped resources that the c
|
|||||||
## Connector discovery
|
## Connector discovery
|
||||||
|
|
||||||
A connector is shipped as a folder containing a `connector.json` manifest and
|
A connector is shipped as a folder containing a `connector.json` manifest and
|
||||||
an executable entry point. The IfcViewer discovers connectors by scanning a
|
an executable entry point. The Bonsai Viewer discovers connectors by scanning a
|
||||||
small, fixed set of locations for these folders.
|
small, fixed set of locations for these folders.
|
||||||
|
|
||||||
### Connector bundle layout
|
### Connector bundle layout
|
||||||
@@ -447,7 +447,7 @@ small, fixed set of locations for these folders.
|
|||||||
<some-connectors-dir>/
|
<some-connectors-dir>/
|
||||||
autodesk/ # folder name is arbitrary; id comes from connector.json
|
autodesk/ # folder name is arbitrary; id comes from connector.json
|
||||||
connector.json # required, at the folder root
|
connector.json # required, at the folder root
|
||||||
ifcviewer-autodesk # the executable (or a wrapper script)
|
bonsaiviewer-autodesk # the executable (or a wrapper script)
|
||||||
... # anything else the connector ships
|
... # anything else the connector ships
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -458,38 +458,38 @@ small, fixed set of locations for these folders.
|
|||||||
"id": "autodesk",
|
"id": "autodesk",
|
||||||
"name": "Autodesk Forma",
|
"name": "Autodesk Forma",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"exec": "./ifcviewer-autodesk"
|
"exec": "./bonsaiviewer-autodesk"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- `id` — stable identifier used in `.ifcfed` `source.connector` fields and in
|
- `id` — stable identifier used in `.ifcfed` `source.connector` fields and in
|
||||||
`.ifcfed.manifest`. Must be unique across all discovered connectors.
|
`.ifcfed.manifest`. Must be unique across all discovered connectors.
|
||||||
- `name` — human-readable label shown in the IfcViewer UI.
|
- `name` — human-readable label shown in the Bonsai Viewer UI.
|
||||||
- `version` — connector version string; informational only.
|
- `version` — connector version string; informational only.
|
||||||
- `exec` — path to the connector executable. Relative paths are resolved
|
- `exec` — path to the connector executable. Relative paths are resolved
|
||||||
against the connector folder; absolute paths are used as-is. Bundled
|
against the connector folder; absolute paths are used as-is. Bundled
|
||||||
connectors should use a relative path so the bundle is self-contained.
|
connectors should use a relative path so the bundle is self-contained.
|
||||||
|
|
||||||
On Windows, the IfcViewer will also try `<exec>.exe` if `<exec>` does not
|
On Windows, the Bonsai Viewer will also try `<exec>.exe` if `<exec>` does not
|
||||||
exist as written.
|
exist as written.
|
||||||
|
|
||||||
### Search locations
|
### Search locations
|
||||||
|
|
||||||
The IfcViewer scans the **user connectors directory**. The platform's per-user
|
The Bonsai Viewer scans the **user connectors directory**. The platform's per-user
|
||||||
application data location:
|
application data location:
|
||||||
|
|
||||||
- Linux: `~/.local/share/IfcOpenShell/BonsaiViewer/connectors/`
|
- Linux: `~/.local/share/IfcOpenShell/BonsaiViewer/connectors/`
|
||||||
- macOS: `~/Library/Application Support/IfcOpenShell/BonsaiViewer/connectors/`
|
- macOS: `~/Library/Application Support/IfcOpenShell/BonsaiViewer/connectors/`
|
||||||
- Windows: `%APPDATA%\IfcOpenShell\BonsaiViewer\connectors\`
|
- Windows: `%APPDATA%\IfcOpenShell\BonsaiViewer\connectors\`
|
||||||
|
|
||||||
The IfcViewer looks at every immediate subdirectory and treats it as a
|
The Bonsai Viewer looks at every immediate subdirectory and treats it as a
|
||||||
connector iff it contains a `connector.json`. Connectors are launched on
|
connector iff it contains a `connector.json`. Connectors are launched on
|
||||||
demand when the user invokes a cloud workflow, not at startup.
|
demand when the user invokes a cloud workflow, not at startup.
|
||||||
|
|
||||||
### Conflicts and errors
|
### Conflicts and errors
|
||||||
|
|
||||||
- If two folders declare the same `id`, the one found earlier in directory
|
- If two folders declare the same `id`, the one found earlier in directory
|
||||||
order wins; the loser is skipped and a warning is written to the IfcViewer's
|
order wins; the loser is skipped and a warning is written to the Bonsai Viewer's
|
||||||
log.
|
log.
|
||||||
- A `connector.json` that is missing, unreadable, malformed, or missing
|
- A `connector.json` that is missing, unreadable, malformed, or missing
|
||||||
required fields causes that folder to be skipped (with a log entry); other
|
required fields causes that folder to be skipped (with a log entry); other
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# `ifcviewer-autodesk`
|
# `bonsaiviewer-autodesk`
|
||||||
|
|
||||||
Autodesk Forma (APS / Docs) connector for IfcViewer.
|
Autodesk Forma (APS / Docs) connector for Bonsai Viewer.
|
||||||
|
|
||||||
Implements the JSON-RPC connector contract defined in
|
Implements the JSON-RPC connector contract defined in
|
||||||
[`CLOUD_SYNC_PROTOCOL.md`](CLOUD_SYNC_PROTOCOL.md). The connector is a separate
|
[`CLOUD_SYNC_PROTOCOL.md`](CLOUD_SYNC_PROTOCOL.md). The connector is a separate
|
||||||
@@ -14,7 +14,7 @@ on Gentoo make sure `USE="tk"` is set for `dev-lang/python`).
|
|||||||
## Install
|
## Install
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd src/ifcviewer-autodesk
|
cd src/bonsaiviewer-autodesk
|
||||||
python -m venv venv
|
python -m venv venv
|
||||||
source venv/bin/activate
|
source venv/bin/activate
|
||||||
pip install -e .
|
pip install -e .
|
||||||
@@ -23,7 +23,7 @@ pip install -e .
|
|||||||
## Run
|
## Run
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ifcviewer-autodesk
|
bonsaiviewer-autodesk
|
||||||
```
|
```
|
||||||
|
|
||||||
The connector launches without any configuration; on first run, invoke
|
The connector launches without any configuration; on first run, invoke
|
||||||
@@ -53,9 +53,9 @@ The connector reads the Autodesk client id from two places, in order:
|
|||||||
|
|
||||||
The config directory is platform-specific:
|
The config directory is platform-specific:
|
||||||
|
|
||||||
- Linux: `~/.config/ifcviewer-autodesk/`
|
- Linux: `~/.config/bonsaiviewer-autodesk/`
|
||||||
- macOS: `~/Library/Application Support/ifcviewer-autodesk/`
|
- macOS: `~/Library/Application Support/bonsaiviewer-autodesk/`
|
||||||
- Windows: `%APPDATA%\ifcviewer-autodesk\`
|
- Windows: `%APPDATA%\bonsaiviewer-autodesk\`
|
||||||
|
|
||||||
OAuth tokens are stored in the OS keychain (Secret Service on Linux, Keychain
|
OAuth tokens are stored in the OS keychain (Secret Service on Linux, Keychain
|
||||||
on macOS, Credential Manager on Windows), keyed by the client id, so changing
|
on macOS, Credential Manager on Windows), keyed by the client id, so changing
|
||||||
@@ -66,7 +66,7 @@ the client id starts a fresh session.
|
|||||||
The connector owns its own cache. Resolved files live under (Linux):
|
The connector owns its own cache. Resolved files live under (Linux):
|
||||||
|
|
||||||
```
|
```
|
||||||
~/.cache/ifcviewer-autodesk/
|
~/.cache/bonsaiviewer-autodesk/
|
||||||
ifcfeds/<hash>/<name>.ifcfed[.manifest]
|
ifcfeds/<hash>/<name>.ifcfed[.manifest]
|
||||||
models/<hash>/<filename>
|
models/<hash>/<filename>
|
||||||
```
|
```
|
||||||
+3
-3
@@ -2,9 +2,9 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from ifcviewer_autodesk.connector import AutodeskConnector
|
from bonsaiviewer_autodesk.connector import AutodeskConnector
|
||||||
from ifcviewer_autodesk.rpc import JsonRpcHost
|
from bonsaiviewer_autodesk.rpc import JsonRpcHost
|
||||||
from ifcviewer_autodesk.ui import ensure_tk_app
|
from bonsaiviewer_autodesk.ui import ensure_tk_app
|
||||||
|
|
||||||
|
|
||||||
def main() -> int:
|
def main() -> int:
|
||||||
+1
-1
@@ -17,7 +17,7 @@ import httpx
|
|||||||
import keyring
|
import keyring
|
||||||
import keyring.errors
|
import keyring.errors
|
||||||
|
|
||||||
from ifcviewer_autodesk.rpc import JSONRPC_INTERNAL_ERROR, RpcError
|
from bonsaiviewer_autodesk.rpc import JSONRPC_INTERNAL_ERROR, RpcError
|
||||||
|
|
||||||
|
|
||||||
Progress = Callable[[str, str, "int | None"], None]
|
Progress = Callable[[str, str, "int | None"], None]
|
||||||
+3
-3
@@ -13,12 +13,12 @@ def cache_root() -> Path:
|
|||||||
system = platform.system()
|
system = platform.system()
|
||||||
if system == "Windows":
|
if system == "Windows":
|
||||||
base = os.environ.get("LOCALAPPDATA") or os.path.expanduser("~")
|
base = os.environ.get("LOCALAPPDATA") or os.path.expanduser("~")
|
||||||
root = Path(base) / "ifcviewer-autodesk" / "Cache"
|
root = Path(base) / "bonsaiviewer-autodesk" / "Cache"
|
||||||
elif system == "Darwin":
|
elif system == "Darwin":
|
||||||
root = Path.home() / "Library" / "Caches" / "ifcviewer-autodesk"
|
root = Path.home() / "Library" / "Caches" / "bonsaiviewer-autodesk"
|
||||||
else:
|
else:
|
||||||
base = os.environ.get("XDG_CACHE_HOME") or os.path.expanduser("~/.cache")
|
base = os.environ.get("XDG_CACHE_HOME") or os.path.expanduser("~/.cache")
|
||||||
root = Path(base) / "ifcviewer-autodesk"
|
root = Path(base) / "bonsaiviewer-autodesk"
|
||||||
root.mkdir(parents=True, exist_ok=True)
|
root.mkdir(parents=True, exist_ok=True)
|
||||||
return root
|
return root
|
||||||
|
|
||||||
+5
-5
@@ -5,10 +5,10 @@ import traceback
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Callable
|
from typing import Any, Callable
|
||||||
|
|
||||||
from ifcviewer_autodesk import cache, settings
|
from bonsaiviewer_autodesk import cache, settings
|
||||||
from ifcviewer_autodesk.autodesk import ApsClient, AuthSessionService, KeyringTokenStore
|
from bonsaiviewer_autodesk.autodesk import ApsClient, AuthSessionService, KeyringTokenStore
|
||||||
from ifcviewer_autodesk.rpc import JSONRPC_INTERNAL_ERROR, JSONRPC_INVALID_PARAMS, RpcError
|
from bonsaiviewer_autodesk.rpc import JSONRPC_INTERNAL_ERROR, JSONRPC_INVALID_PARAMS, RpcError
|
||||||
from ifcviewer_autodesk.ui import BrowseDialog, SettingsDialog, progress_dialog, prompt_for_filename
|
from bonsaiviewer_autodesk.ui import BrowseDialog, SettingsDialog, progress_dialog, prompt_for_filename
|
||||||
|
|
||||||
|
|
||||||
ApsProgress = Callable[[str, "int | None"], None]
|
ApsProgress = Callable[[str, "int | None"], None]
|
||||||
@@ -34,7 +34,7 @@ def _upload_callback(report: Report) -> ApsProgress:
|
|||||||
|
|
||||||
|
|
||||||
CONNECTOR_ID = "autodesk"
|
CONNECTOR_ID = "autodesk"
|
||||||
KEYRING_SERVICE = "ifcviewer-autodesk"
|
KEYRING_SERVICE = "bonsaiviewer-autodesk"
|
||||||
DEFAULT_CALLBACK_URL = "http://localhost:8080/"
|
DEFAULT_CALLBACK_URL = "http://localhost:8080/"
|
||||||
DEFAULT_SCOPE = "data:read data:write data:create"
|
DEFAULT_SCOPE = "data:read data:write data:create"
|
||||||
|
|
||||||
+3
-3
@@ -11,12 +11,12 @@ def config_root() -> Path:
|
|||||||
system = platform.system()
|
system = platform.system()
|
||||||
if system == "Windows":
|
if system == "Windows":
|
||||||
base = os.environ.get("APPDATA") or os.path.expanduser("~")
|
base = os.environ.get("APPDATA") or os.path.expanduser("~")
|
||||||
root = Path(base) / "ifcviewer-autodesk"
|
root = Path(base) / "bonsaiviewer-autodesk"
|
||||||
elif system == "Darwin":
|
elif system == "Darwin":
|
||||||
root = Path.home() / "Library" / "Application Support" / "ifcviewer-autodesk"
|
root = Path.home() / "Library" / "Application Support" / "bonsaiviewer-autodesk"
|
||||||
else:
|
else:
|
||||||
base = os.environ.get("XDG_CONFIG_HOME") or os.path.expanduser("~/.config")
|
base = os.environ.get("XDG_CONFIG_HOME") or os.path.expanduser("~/.config")
|
||||||
root = Path(base) / "ifcviewer-autodesk"
|
root = Path(base) / "bonsaiviewer-autodesk"
|
||||||
root.mkdir(parents=True, exist_ok=True)
|
root.mkdir(parents=True, exist_ok=True)
|
||||||
return root
|
return root
|
||||||
|
|
||||||
+12
-5
@@ -6,12 +6,12 @@ from typing import TYPE_CHECKING, Any, Callable, Literal
|
|||||||
|
|
||||||
import customtkinter as ctk
|
import customtkinter as ctk
|
||||||
|
|
||||||
from ifcviewer_autodesk import settings
|
from bonsaiviewer_autodesk import settings
|
||||||
from ifcviewer_autodesk.autodesk import ApsClient, AuthSessionService, KeyringTokenStore
|
from bonsaiviewer_autodesk.autodesk import ApsClient, AuthSessionService, KeyringTokenStore
|
||||||
from ifcviewer_autodesk.rpc import JSONRPC_INTERNAL_ERROR, RpcError
|
from bonsaiviewer_autodesk.rpc import JSONRPC_INTERNAL_ERROR, RpcError
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from ifcviewer_autodesk.connector import AutodeskConnector
|
from bonsaiviewer_autodesk.connector import AutodeskConnector
|
||||||
|
|
||||||
|
|
||||||
MODEL_EXTENSIONS = (".ifc", ".ifcview", ".rdb", ".rdbview")
|
MODEL_EXTENSIONS = (".ifc", ".ifcview", ".rdb", ".rdbview")
|
||||||
@@ -161,10 +161,17 @@ class _ProgressContext:
|
|||||||
def __exit__(self, *_exc: object) -> None:
|
def __exit__(self, *_exc: object) -> None:
|
||||||
if self.dialog is not None:
|
if self.dialog is not None:
|
||||||
try:
|
try:
|
||||||
|
self.dialog.withdraw()
|
||||||
self.dialog.destroy()
|
self.dialog.destroy()
|
||||||
except tk.TclError:
|
except tk.TclError:
|
||||||
pass
|
pass
|
||||||
self.dialog = None
|
self.dialog = None
|
||||||
|
try:
|
||||||
|
root = ensure_tk_app()
|
||||||
|
root.update_idletasks()
|
||||||
|
root.update()
|
||||||
|
except tk.TclError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def progress_dialog(message: str) -> _ProgressContext:
|
def progress_dialog(message: str) -> _ProgressContext:
|
||||||
@@ -629,7 +636,7 @@ class SettingsDialog(_BaseDialog):
|
|||||||
):
|
):
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
KeyringTokenStore(service_name="ifcviewer-autodesk", username=client_id).delete()
|
KeyringTokenStore(service_name="bonsaiviewer-autodesk", username=client_id).delete()
|
||||||
except RpcError as exc:
|
except RpcError as exc:
|
||||||
show_error(title="Sign Out Failed", message=exc.message)
|
show_error(title="Sign Out Failed", message=exc.message)
|
||||||
return
|
return
|
||||||
@@ -2,5 +2,5 @@
|
|||||||
"id": "autodesk",
|
"id": "autodesk",
|
||||||
"name": "Autodesk Forma",
|
"name": "Autodesk Forma",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"exec": "ifcviewer-autodesk"
|
"exec": "bonsaiviewer-autodesk"
|
||||||
}
|
}
|
||||||
+6
-6
@@ -1,7 +1,7 @@
|
|||||||
# Packaging the Autodesk connector
|
# Packaging the Autodesk connector
|
||||||
|
|
||||||
The connector is shipped as a self-contained folder ready to drop into the
|
The connector is shipped as a self-contained folder ready to drop into the
|
||||||
IfcViewer connectors directory. PyInstaller bundles the Python interpreter,
|
Bonsai Viewer connectors directory. PyInstaller bundles the Python interpreter,
|
||||||
Qt, and all dependencies so end users do not need Python installed.
|
Qt, and all dependencies so end users do not need Python installed.
|
||||||
|
|
||||||
PyInstaller does **not** cross-compile. Each OS must build on itself —
|
PyInstaller does **not** cross-compile. Each OS must build on itself —
|
||||||
@@ -13,7 +13,7 @@ typically via a CI matrix.
|
|||||||
dist/
|
dist/
|
||||||
autodesk/ # the connector folder, ready to install
|
autodesk/ # the connector folder, ready to install
|
||||||
connector.json
|
connector.json
|
||||||
ifcviewer-autodesk[.exe]
|
bonsaiviewer-autodesk[.exe]
|
||||||
_internal/... # PyInstaller dependencies (Qt, Python, …)
|
_internal/... # PyInstaller dependencies (Qt, Python, …)
|
||||||
autodesk-<os>-<arch>.zip # the distribution archive
|
autodesk-<os>-<arch>.zip # the distribution archive
|
||||||
```
|
```
|
||||||
@@ -24,7 +24,7 @@ The folder is what Bonsai Viewer expects under
|
|||||||
## Build steps (any OS)
|
## Build steps (any OS)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd src/ifcviewer-autodesk
|
cd src/bonsaiviewer-autodesk
|
||||||
python -m venv venv
|
python -m venv venv
|
||||||
venv/bin/activate # or venv\Scripts\activate on Windows
|
venv/bin/activate # or venv\Scripts\activate on Windows
|
||||||
pip install -e ".[build]"
|
pip install -e ".[build]"
|
||||||
@@ -34,7 +34,7 @@ python packaging/build.py
|
|||||||
The build:
|
The build:
|
||||||
|
|
||||||
1. cleans `dist/` and `build/`
|
1. cleans `dist/` and `build/`
|
||||||
2. runs PyInstaller against `packaging/ifcviewer-autodesk.spec`
|
2. runs PyInstaller against `packaging/bonsaiviewer-autodesk.spec`
|
||||||
3. renames the produced folder to `autodesk/` and copies `connector.json` into it
|
3. renames the produced folder to `autodesk/` and copies `connector.json` into it
|
||||||
4. zips the folder as `autodesk-<os>-<arch>.zip`
|
4. zips the folder as `autodesk-<os>-<arch>.zip`
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ builds do; on Gentoo make sure `USE="tk"` is set for `dev-lang/python`.
|
|||||||
any modern Python distribution).
|
any modern Python distribution).
|
||||||
- The keyring backend is Credential Manager.
|
- The keyring backend is Credential Manager.
|
||||||
- The `.exe` is built with `console=True` because the connector speaks
|
- The `.exe` is built with `console=True` because the connector speaks
|
||||||
JSON-RPC over stdio. The IfcViewer must launch the connector with
|
JSON-RPC over stdio. The Bonsai Viewer must launch the connector with
|
||||||
`CREATE_NO_WINDOW` (Qt: `QProcess::setCreateProcessArgumentsModifier`) so
|
`CREATE_NO_WINDOW` (Qt: `QProcess::setCreateProcessArgumentsModifier`) so
|
||||||
end users never see a console window flicker.
|
end users never see a console window flicker.
|
||||||
- For distribution: sign the `.exe` with an Authenticode certificate to
|
- For distribution: sign the `.exe` with an Authenticode certificate to
|
||||||
@@ -98,5 +98,5 @@ Bonsai Viewer picks up the connector on next launch.
|
|||||||
|
|
||||||
- Signing / notarization (caller's responsibility per OS)
|
- Signing / notarization (caller's responsibility per OS)
|
||||||
- CI matrix (project-level concern)
|
- CI matrix (project-level concern)
|
||||||
- Auto-update (the IfcViewer or the host installer handles this)
|
- Auto-update (the Bonsai Viewer or the host installer handles this)
|
||||||
- Universal macOS binaries via `lipo` (post-process step, not part of `build.py`)
|
- Universal macOS binaries via `lipo` (post-process step, not part of `build.py`)
|
||||||
+5
-5
@@ -1,7 +1,7 @@
|
|||||||
# PyInstaller spec for the IfcViewer Autodesk connector (Tk + CustomTkinter).
|
# PyInstaller spec for the Bonsai Viewer Autodesk connector (Tk + CustomTkinter).
|
||||||
#
|
#
|
||||||
# The connector talks JSON-RPC over stdio, so `console=True` is required to
|
# The connector talks JSON-RPC over stdio, so `console=True` is required to
|
||||||
# attach stdin/stdout on Windows. The IfcViewer is expected to spawn the
|
# attach stdin/stdout on Windows. The Bonsai Viewer is expected to spawn the
|
||||||
# connector with the OS's "hide console window" flag on Windows
|
# connector with the OS's "hide console window" flag on Windows
|
||||||
# (CREATE_NO_WINDOW) so end users never see a console pop up.
|
# (CREATE_NO_WINDOW) so end users never see a console pop up.
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ HIDDEN_IMPORTS = [
|
|||||||
|
|
||||||
|
|
||||||
a = Analysis(
|
a = Analysis(
|
||||||
[str(PROJECT_ROOT / "ifcviewer_autodesk" / "__main__.py")],
|
[str(PROJECT_ROOT / "bonsaiviewer_autodesk" / "__main__.py")],
|
||||||
pathex=[str(PROJECT_ROOT)],
|
pathex=[str(PROJECT_ROOT)],
|
||||||
binaries=[],
|
binaries=[],
|
||||||
datas=[],
|
datas=[],
|
||||||
@@ -56,7 +56,7 @@ exe = EXE(
|
|||||||
a.scripts,
|
a.scripts,
|
||||||
[],
|
[],
|
||||||
exclude_binaries=True,
|
exclude_binaries=True,
|
||||||
name="ifcviewer-autodesk",
|
name="bonsaiviewer-autodesk",
|
||||||
debug=False,
|
debug=False,
|
||||||
bootloader_ignore_signals=False,
|
bootloader_ignore_signals=False,
|
||||||
strip=False,
|
strip=False,
|
||||||
@@ -77,5 +77,5 @@ coll = COLLECT(
|
|||||||
strip=False,
|
strip=False,
|
||||||
upx=True,
|
upx=True,
|
||||||
upx_exclude=[],
|
upx_exclude=[],
|
||||||
name="ifcviewer-autodesk",
|
name="bonsaiviewer-autodesk",
|
||||||
)
|
)
|
||||||
+5
-5
@@ -1,12 +1,12 @@
|
|||||||
"""Build the Autodesk connector bundle for the current OS.
|
"""Build the Autodesk connector bundle for the current OS.
|
||||||
|
|
||||||
Each OS builds on itself (PyInstaller does not cross-compile). The output is a
|
Each OS builds on itself (PyInstaller does not cross-compile). The output is a
|
||||||
single zip ready to drop into the IfcViewer connectors directory:
|
single zip ready to drop into the Bonsai Viewer connectors directory:
|
||||||
|
|
||||||
dist/autodesk-<os>-<arch>.zip
|
dist/autodesk-<os>-<arch>.zip
|
||||||
autodesk/
|
autodesk/
|
||||||
connector.json
|
connector.json
|
||||||
ifcviewer-autodesk[.exe]
|
bonsaiviewer-autodesk[.exe]
|
||||||
_internal/...
|
_internal/...
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
@@ -27,12 +27,12 @@ from pathlib import Path
|
|||||||
|
|
||||||
PROJECT_ROOT = Path(__file__).resolve().parent.parent
|
PROJECT_ROOT = Path(__file__).resolve().parent.parent
|
||||||
PACKAGING_DIR = PROJECT_ROOT / "packaging"
|
PACKAGING_DIR = PROJECT_ROOT / "packaging"
|
||||||
SPEC_FILE = PACKAGING_DIR / "ifcviewer-autodesk.spec"
|
SPEC_FILE = PACKAGING_DIR / "bonsaiviewer-autodesk.spec"
|
||||||
DIST_DIR = PROJECT_ROOT / "dist"
|
DIST_DIR = PROJECT_ROOT / "dist"
|
||||||
BUILD_DIR = PROJECT_ROOT / "build"
|
BUILD_DIR = PROJECT_ROOT / "build"
|
||||||
|
|
||||||
CONNECTOR_FOLDER_NAME = "autodesk"
|
CONNECTOR_FOLDER_NAME = "autodesk"
|
||||||
PYINSTALLER_OUTPUT_NAME = "ifcviewer-autodesk"
|
PYINSTALLER_OUTPUT_NAME = "bonsaiviewer-autodesk"
|
||||||
|
|
||||||
|
|
||||||
def _platform_tag() -> str:
|
def _platform_tag() -> str:
|
||||||
@@ -92,7 +92,7 @@ def _assemble_connector_folder(pyinstaller_output: Path) -> Path:
|
|||||||
# `pip install -e .` works for development. For the bundled folder, the
|
# `pip install -e .` works for development. For the bundled folder, the
|
||||||
# binary lives next to connector.json, so rewrite `exec` to a relative path.
|
# binary lives next to connector.json, so rewrite `exec` to a relative path.
|
||||||
manifest = json.loads((PROJECT_ROOT / "connector.json").read_text(encoding="utf-8"))
|
manifest = json.loads((PROJECT_ROOT / "connector.json").read_text(encoding="utf-8"))
|
||||||
binary_name = "ifcviewer-autodesk.exe" if platform.system() == "Windows" else "ifcviewer-autodesk"
|
binary_name = "bonsaiviewer-autodesk.exe" if platform.system() == "Windows" else "bonsaiviewer-autodesk"
|
||||||
manifest["exec"] = f"./{binary_name}"
|
manifest["exec"] = f"./{binary_name}"
|
||||||
(connector_dir / "connector.json").write_text(json.dumps(manifest, indent=2) + "\n", encoding="utf-8")
|
(connector_dir / "connector.json").write_text(json.dumps(manifest, indent=2) + "\n", encoding="utf-8")
|
||||||
|
|
||||||
@@ -3,9 +3,9 @@ requires = ["setuptools>=69", "wheel"]
|
|||||||
build-backend = "setuptools.build_meta"
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "ifcviewer-autodesk"
|
name = "bonsaiviewer-autodesk"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "Autodesk cloud connector for IfcViewer"
|
description = "Autodesk cloud connector for Bonsai Viewer"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.11"
|
requires-python = ">=3.11"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
@@ -24,4 +24,4 @@ include-package-data = true
|
|||||||
where = ["."]
|
where = ["."]
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
ifcviewer-autodesk = "ifcviewer_autodesk.__main__:main"
|
bonsaiviewer-autodesk = "bonsaiviewer_autodesk.__main__:main"
|
||||||
Reference in New Issue
Block a user