summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkarnigen <karnigen@gmail.com>2023-12-25 19:54:52 +0100
committerkarnigen <karnigen@gmail.com>2023-12-25 19:54:52 +0100
commitfe323375e42253f00fd378fbaff1a3373385fccc (patch)
tree6676a09071cbe9bb9df4dd113ab4f6ff8c571441
parent746768d849dfb72c7f0b2b4a264f153fd3b6e242 (diff)
env update from inkscape, bash names for script
-rw-r--r--inkstitch.py114
-rw-r--r--lib/debug_utils.py36
2 files changed, 84 insertions, 66 deletions
diff --git a/inkstitch.py b/inkstitch.py
index e5ef3d7a..e0c968b6 100644
--- a/inkstitch.py
+++ b/inkstitch.py
@@ -11,11 +11,17 @@ from pathlib import Path
SCRIPTDIR = Path(__file__).parent.absolute()
if len(sys.argv) < 2:
- exit(1) # no arguments - prevent uncidentally running this script
+ exit(1) # no arguments - prevent accidentally running this script
+
+prefere_pip_inkex = True # prefer pip installed inkex over inkscape bundled inkex
+
+# define names of files used by offline Bash script
+bash_name = ".ink.sh"
+bash_svg = ".ink.svg"
running_as_frozen = getattr(sys, 'frozen', None) is not None # check if running from pyinstaller bundle
-running_from_inkscape = '.ink.svg' not in sys.argv # inkscape never starts extension with .ink.svg file in args
-# running_from_inkscape = True # for testing
+# we assume that if arguments contain svg file (=.ink.svg) then we are running not from inkscape
+running_from_inkscape = bash_svg not in sys.argv
debug_active = bool((gettrace := getattr(sys, 'gettrace')) and gettrace()) # check if debugger is active on startup
debug_file = SCRIPTDIR / "DEBUG"
@@ -24,53 +30,59 @@ debug_type = 'none'
profile_file = SCRIPTDIR / "PROFILE"
profile_type = 'none'
-# print(f"debug_type:'{debug_type}' profile_type:'{profile_type}'", file=sys.stderr) # for testing
-
-# if script was already started from debugger then don't read debug file
-if not running_as_frozen and not debug_active and os.path.exists(debug_file):
- debug_type = debug_utils.parse_file(debug_file) # read type of debugger from debug_file DEBUG
- if debug_type == 'none': # for better backward compatibility
- print(f"Debug file exists but no debugger type found in '{debug_file.name}'", file=sys.stderr)
-
-if os.path.exists(profile_file):
- profile_type = debug_utils.parse_file(profile_file) # read type of profiler from profile_file PROFILE
- if profile_type == 'none': # for better backward compatibility
- print(f"Profile file exists but no profiler type found in '{profile_file.name}'", file=sys.stderr)
-
-if running_from_inkscape:
- if debug_type.endswith('-script'): # if offline debugging just create script for later debugging
- debug_utils.write_offline_debug_script(SCRIPTDIR)
- debug_type = 'none' # do not start debugger when running from inkscape
-else: # not running from inkscape
- if debug_type.endswith('-script'): # remove '-script' to propely initialize debugger packages for each editor
- debug_type = debug_type.replace('-script', '')
-
-if not running_as_frozen:
- # When running in development mode, we prefer inkex installed by pip, not the one bundled with Inkscape.
- # - move inkscape extensions path to the end of sys.path
- # - we compare PYTHONPATH with sys.path and move PYTHONPATH to the end of sys.path
- # - also user inkscape extensions path is moved to the end of sys.path - may cause problems?
- # - path for deprecated-simple are removed from sys.path, will be added later by importing inkex
-
- # PYTHONPATH to list
- pythonpath = os.environ.get('PYTHONPATH', '').split(os.pathsep)
- # remove pythonpath from sys.path
- sys.path = [p for p in sys.path if p not in pythonpath]
- # remove deprecated-simple, it will be added later by importing inkex
- pythonpath = [p for p in pythonpath if not p.endswith('deprecated-simple')]
- # add pythonpath to the end of sys.path
- sys.path.extend(pythonpath)
-
- # >> should be removed after previous code was tested <<
- # if sys.platform == "darwin":
- # extensions_path = "/Applications/Inkscape.app/Contents/Resources/share/inkscape/extensions" # Mac
- # else:
- # extensions_path = "/usr/share/inkscape/extensions" # Linux
- # # windows not solved
- # move inkscape extensions path to the end of sys.path
- # sys.path.remove(extensions_path)
- # sys.path.append(extensions_path)
- # >> ------------------------------------------------- <<
+if not running_as_frozen: # debugging/profiling only in development mode
+ # parse debug file
+ # - if script was already started from debugger then don't read debug file
+ if not debug_active and os.path.exists(debug_file):
+ debug_type = debug_utils.parse_file(debug_file) # read type of debugger from debug_file DEBUG
+ if debug_type == 'none': # for better backward compatibility
+ print(f"Debug file exists but no debugger type found in '{debug_file.name}'", file=sys.stderr)
+
+ # parse profile file
+ if os.path.exists(profile_file):
+ profile_type = debug_utils.parse_file(profile_file) # read type of profiler from profile_file PROFILE
+ if profile_type == 'none': # for better backward compatibility
+ print(f"Profile file exists but no profiler type found in '{profile_file.name}'", file=sys.stderr)
+
+ # process creation of the Bash script
+ if running_from_inkscape:
+ if debug_type.endswith('-script'): # if offline debugging just create script for later debugging
+ debug_utils.write_offline_debug_script(SCRIPTDIR, bash_name, bash_svg)
+ debug_type = 'none' # do not start debugger when running from inkscape
+ else: # not running from inkscape
+ if debug_type.endswith('-script'): # remove '-script' to propely initialize debugger packages for each editor
+ debug_type = debug_type.replace('-script', '')
+
+ if prefere_pip_inkex and 'PYTHONPATH' in os.environ:
+ # see static void set_extensions_env() in inkscape/src/inkscape-main.cpp
+
+ # When running in development mode, we prefer inkex installed by pip, not the one bundled with Inkscape.
+ # - move inkscape extensions path to the end of sys.path
+ # - we compare PYTHONPATH with sys.path and move PYTHONPATH to the end of sys.path
+ # - also user inkscape extensions path is moved to the end of sys.path - may cause problems?
+ # - path for deprecated-simple are removed from sys.path, will be added later by importing inkex
+
+ # PYTHONPATH to list
+ pythonpath = os.environ.get('PYTHONPATH', '').split(os.pathsep)
+ # remove pythonpath from sys.path
+ sys.path = [p for p in sys.path if p not in pythonpath]
+ # remove deprecated-simple, it will be added later by importing inkex
+ pythonpath = [p for p in pythonpath if not p.endswith('deprecated-simple')]
+ # remove nonexisting paths
+ pythonpath = [p for p in pythonpath if os.path.exists(p)]
+ # add pythonpath to the end of sys.path
+ sys.path.extend(pythonpath)
+
+ # >> should be removed after previous code was tested <<
+ # if sys.platform == "darwin":
+ # extensions_path = "/Applications/Inkscape.app/Contents/Resources/share/inkscape/extensions" # Mac
+ # else:
+ # extensions_path = "/usr/share/inkscape/extensions" # Linux
+ # # windows ?
+ # move inkscape extensions path to the end of sys.path
+ # sys.path.remove(extensions_path)
+ # sys.path.append(extensions_path)
+ # >> ------------------------------------------------- <<
import logging
from argparse import ArgumentParser
@@ -122,7 +134,7 @@ extension = extension_class() # create instance of extension class - call __ini
# extension run(), but we differentiate between debug and normal mode
# - in debug or profile mode we run extension or profile extension
-# - in normal mode we run extension in try/except block to catch all exceptions
+# - in normal mode we run extension in try/except block to catch all exceptions and hide GTK spam
if debug_active or profile_type != "none": # if debug or profile mode
print(f"Extension:'{extension_name}' Debug active:{debug_active} type:'{debug_type}' "
f"Profile type:'{profile_type}'", file=sys.stderr)
diff --git a/lib/debug_utils.py b/lib/debug_utils.py
index 6555b083..b5d7aa6a 100644
--- a/lib/debug_utils.py
+++ b/lib/debug_utils.py
@@ -17,6 +17,7 @@ import sys
# as "vscode-script" or "pycharm-script" or "pydev-script"
# - in that case running from inkscape will not start debugger
# but prepare script for offline debugging from console
+# - valid for "none-script" too
# - backward compatibilty is broken due to confusion
# debug_type = 'pydev' # default debugger backwards compatibility
# if 'PYCHARM_REMOTE_DEBUG' in os.environ: # backwards compatibility
@@ -44,14 +45,14 @@ def parse_file(filename):
break
return value_type
-def write_offline_debug_script(SCRIPTDIR):
+def write_offline_debug_script(SCRIPTDIR, bash_name, bash_svg):
# prepare script for offline debugging from console
# - only tested on linux
import shutil
- ink_file = os.path.join(SCRIPTDIR, ".ink.sh")
+ ink_file = os.path.join(SCRIPTDIR, bash_name)
with open(ink_file, 'w') as f:
f.write(f"#!/usr/bin/env bash\n\n")
- f.write(f"# version: {sys.version}\n") # python version
+ f.write(f"# python version: {sys.version}\n") # python version
myargs = " ".join(sys.argv[1:])
f.write(f'# script: {sys.argv[0]} arguments: {myargs}\n') # script name and arguments
@@ -61,24 +62,29 @@ def write_offline_debug_script(SCRIPTDIR):
for p in sys.path:
f.write(f"# {p}\n")
- # print PYTHONPATH one per line
+ # see static void set_extensions_env() in inkscape/src/inkscape-main.cpp
f.write(f"# PYTHONPATH:\n")
- for p in os.environ.get('PYTHONPATH', '').split(os.pathsep):
+ for p in os.environ.get('PYTHONPATH', '').split(os.pathsep): # PYTHONPATH to list
f.write(f"# {p}\n")
# take argument that not start with '-' as file name
svg_file = " ".join([arg for arg in sys.argv[1:] if not arg.startswith('-')])
- f.write(f"# copy {svg_file} to .ink.svg\n")
- # check if filer are not the same
- if svg_file != '.ink.svg':
- shutil.copy(svg_file, f'{SCRIPTDIR}/.ink.svg') # copy file to .ink.svg
- myargs = myargs.replace(svg_file, '.ink.svg') # replace file name with .ink.svg
+ f.write(f"# copy {svg_file} to {bash_svg}\n")
+ # check if files are not the same
+ if svg_file != bash_svg:
+ shutil.copy(svg_file, SCRIPTDIR / bash_svg) # copy file to bash_svg
+ myargs = myargs.replace(svg_file, bash_svg) # replace file name with bash_svg
- # export INK*|PYTHON* environment variables
- for k, v in sorted(os.environ.items()):
- if k.startswith('INK') or k.startswith('PYTHON'):
- f.write(f'export {k}="{v}"\n')
+ # see void Extension::set_environment() in inkscape/src/extension/extension.cpp
+ notexported = ["SELF_CALL"] # if an extension calls inkscape itself
+ exported = ["INKEX_GETTEXT_DOMAIN", "INKEX_GETTEXT_DIRECTORY",
+ "INKSCAPE_PROFILE_DIR", "DOCUMENT_PATH", "PYTHONPATH"]
+ for k in notexported:
+ if k in os.environ:
+ f.write(f'# export {k}="{os.environ[k]}"\n')
+ for k in exported:
+ if k in os.environ:
+ f.write(f'export {k}="{os.environ[k]}"\n')
- # f.write(f"# python3 -m debugpy --listen 5678 --wait-for-client inkstitch.py {myargs}\n")
f.write(f"python3 inkstitch.py {myargs}\n")
os.chmod(ink_file, 0o0755) # make file executable