BlenderBIM ifc file association (linux only) #2399

This commit is contained in:
Bruno Postle
2023-05-07 13:08:28 +01:00
parent b987d5ca7c
commit d7a74dd6a4
12 changed files with 131 additions and 0 deletions
+3
View File
@@ -664,6 +664,9 @@ endif
cp -r dist/working/bpypolyskel-master/bpypolyskel dist/blenderbim/libs/site/packages/ cp -r dist/working/bpypolyskel-master/bpypolyskel dist/blenderbim/libs/site/packages/
rm -rf dist/working rm -rf dist/working
# Required for Desktop icon and file association
cp -r blenderbim/libs/desktop dist/blenderbim/libs/
# Remove dependencies also bundled with Blender # Remove dependencies also bundled with Blender
rm -rf dist/blenderbim/libs/site/packages/numpy rm -rf dist/blenderbim/libs/site/packages/numpy
rm -rf dist/blenderbim/libs/site/packages/numpy.libs rm -rf dist/blenderbim/libs/site/packages/numpy.libs
@@ -95,6 +95,8 @@ classes = [
operator.SelectIfcFile, operator.SelectIfcFile,
operator.ReloadSelectedIfcFile, operator.ReloadSelectedIfcFile,
operator.SelectSchemaDir, operator.SelectSchemaDir,
operator.FileAssociate,
operator.FileUnassociate,
operator.SelectURIAttribute, operator.SelectURIAttribute,
operator.EditBlenderCollection, operator.EditBlenderCollection,
operator.BIM_OT_open_webbrowser, operator.BIM_OT_open_webbrowser,
+123
View File
@@ -22,6 +22,9 @@ import json
import time import time
import logging import logging
import textwrap import textwrap
import shutil
import platform
import subprocess
import tempfile import tempfile
import webbrowser import webbrowser
import ifcopenshell import ifcopenshell
@@ -148,6 +151,126 @@ class SelectSchemaDir(bpy.types.Operator):
return {"RUNNING_MODAL"} return {"RUNNING_MODAL"}
class FileAssociate(bpy.types.Operator):
bl_idname = "bim.file_associate"
bl_label = "Associate BlenderBIM with *.ifc files"
bl_options = {"REGISTER", "UNDO"}
bl_description = "Creates a Desktop launcher and associates it with IFC files"
@classmethod
def poll(cls, context):
if platform.system() == "Linux":
return True
# TODO Windows and Darwin
# https://stackoverflow.com/questions/1082889/how-to-change-filetype-association-in-the-registry
return False
def execute(self, context):
src_dir = os.path.join(os.path.dirname(__file__), "../libs/desktop")
binary_path = bpy.app.binary_path
if platform.system() == "Linux":
destdir = os.path.join(os.environ["HOME"], ".local")
self.install_desktop_linux(src_dir=src_dir, destdir=destdir, binary_path=binary_path)
return {"FINISHED"}
def install_desktop_linux(self, src_dir=None, destdir="/tmp", binary_path="/usr/bin/blender"):
"""Creates linux file assocations and launcher icon"""
for rel_path in (
"bin",
"share/icons/hicolor/128x128/apps",
"share/icons/hicolor/128x128/mimetypes",
"share/applications",
"share/mime/packages",
):
os.makedirs(os.path.join(destdir, rel_path), exist_ok=True)
shutil.copy(
os.path.join(src_dir, "blenderbim.png"),
os.path.join(destdir, "share/icons/hicolor/128x128/apps"),
)
shutil.copy(
os.path.join(src_dir, "blenderbim.desktop"),
os.path.join(destdir, "share/applications"),
)
shutil.copy(
os.path.join(src_dir, "blenderbim.xml"),
os.path.join(destdir, "share/mime/packages"),
)
shutil.copyfile(
os.path.join(src_dir, "x-ifc_128x128.png"),
os.path.join(destdir, "share/icons/hicolor/128x128/mimetypes", "x-ifc.png"),
)
# copy and rewrite wrapper script
with open(os.path.join(src_dir, "blenderbim"), "r") as wrapper_template:
filedata = wrapper_template.read()
filedata = filedata.replace("#BLENDER_EXE=/opt/blender-3.3/blender", 'BLENDER_EXE="' + binary_path + '"')
with open(os.path.join(destdir, "bin", "blenderbim"), "w") as wrapper:
wrapper.write(filedata)
os.chmod(os.path.join(destdir, "bin", "blenderbim"), 0o755)
self.refresh_system_linux(destdir=destdir)
def refresh_system_linux(self, destdir="/tmp"):
"""Attempt to update mime and desktop databases"""
try:
subprocess.call(["update-mime-database", os.path.join(destdir, "share/mime")])
except:
pass
try:
subprocess.call(["update-desktop-database", os.path.join(destdir, "share/applications")])
except:
pass
class FileUnassociate(bpy.types.Operator):
bl_idname = "bim.file_unassociate"
bl_label = "Remove BlenderBIM *.ifc association"
bl_options = {"REGISTER", "UNDO"}
bl_description = "Removes Desktop launcher and unassociates it with IFC files"
@classmethod
def poll(cls, context):
if platform.system() == "Linux":
return True
return False
def execute(self, context):
if platform.system() == "Linux":
destdir = os.path.join(os.environ["HOME"], ".local")
self.uninstall_desktop_linux(destdir=destdir)
return {"FINISHED"}
def uninstall_desktop_linux(self, destdir="/tmp"):
"""Removes linux file assocations and launcher icon"""
for rel_path in (
"share/icons/hicolor/128x128/apps/blenderbim.png",
"share/icons/hicolor/128x128/mimetypes/x-ifc.png",
"share/applications/blenderbim.desktop",
"share/mime/packages/blenderbim.xml",
"bin/blenderbim",
):
try:
os.remove(os.path.join(destdir, rel_path))
except:
pass
self.refresh_system_linux(destdir=destdir)
def refresh_system_linux(self, destdir="/tmp"):
"""Attempt to update mime and desktop databases"""
try:
subprocess.call(["update-mime-database", os.path.join(destdir, "share/mime")])
except:
pass
try:
subprocess.call(["update-desktop-database", os.path.join(destdir, "share/applications")])
except:
pass
class OpenUpstream(bpy.types.Operator): class OpenUpstream(bpy.types.Operator):
bl_idname = "bim.open_upstream" bl_idname = "bim.open_upstream"
bl_label = "Open Upstream Reference" bl_label = "Open Upstream Reference"
+3
View File
@@ -175,6 +175,9 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
row.operator("bim.open_upstream", text="Visit Wiki").page = "wiki" row.operator("bim.open_upstream", text="Visit Wiki").page = "wiki"
row.operator("bim.open_upstream", text="Visit Community").page = "community" row.operator("bim.open_upstream", text="Visit Community").page = "community"
row = layout.row() row = layout.row()
row.operator("bim.file_associate", icon="LOCKVIEW_ON")
row.operator("bim.file_unassociate", icon="LOCKVIEW_OFF")
row = layout.row()
row.prop(self, "svg2pdf_command") row.prop(self, "svg2pdf_command")
row = layout.row() row = layout.row()
row.prop(self, "svg2dxf_command") row.prop(self, "svg2dxf_command")

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB