summaryrefslogtreecommitdiffstats
path: root/share/extensions/inkex/deprecated.py
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:29:01 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:29:01 +0000
commit35a96bde514a8897f6f0fcc41c5833bf63df2e2a (patch)
tree657d15a03cc46bd099fc2c6546a7a4ad43815d9f /share/extensions/inkex/deprecated.py
parentInitial commit. (diff)
downloadinkscape-upstream.tar.xz
inkscape-upstream.zip
Adding upstream version 1.0.2.upstream/1.0.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'share/extensions/inkex/deprecated.py')
-rw-r--r--share/extensions/inkex/deprecated.py388
1 files changed, 388 insertions, 0 deletions
diff --git a/share/extensions/inkex/deprecated.py b/share/extensions/inkex/deprecated.py
new file mode 100644
index 0000000..b7c73ef
--- /dev/null
+++ b/share/extensions/inkex/deprecated.py
@@ -0,0 +1,388 @@
+# coding=utf-8
+#
+# Copyright (C) 2018 - Martin Owens <doctormo@mgail.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+"""
+Provide some documentation to existing extensions about why they're failing.
+"""
+#
+# We ignore a lot of pylint warnings here:
+#
+# pylint: disable=invalid-name,unused-argument,missing-docstring,too-many-public-methods
+#
+
+import os
+import sys
+import traceback
+import warnings
+import argparse
+from argparse import ArgumentParser
+
+import inkex
+import inkex.utils
+import inkex.units
+from inkex.base import SvgThroughMixin, InkscapeExtension
+from inkex.localization import inkex_gettext as _
+
+warnings.simplefilter("default")
+# To load each of the deprecated sub-modules (the ones without a namespace)
+# we will add the directory to our pythonpath so older scripts can find them
+
+INKEX_DIR = os.path.abspath(os.path.dirname(__file__))
+SIMPLE_DIR = os.path.join(INKEX_DIR, 'deprecated-simple')
+
+if os.path.isdir(SIMPLE_DIR):
+ sys.path.append(SIMPLE_DIR)
+
+try:
+ DEPRECATION_LEVEL = int(os.environ.get('INKEX_DEPRECATION_LEVEL', 1))
+except ValueError:
+ DEPRECATION_LEVEL = 1
+
+def _deprecated(msg, stack=2, level=DEPRECATION_LEVEL):
+ """Internal method for raising a deprecation warning"""
+ if level > 1:
+ msg += ' ; '.join(traceback.format_stack())
+ if level:
+ warnings.warn(msg, category=DeprecationWarning, stacklevel=stack + 1)
+
+class DeprecatedEffect(object):
+ """An Inkscape effect, takes SVG in and outputs SVG, providing a deprecated layer"""
+
+ def __init__(self):
+ super(DeprecatedEffect, self).__init__()
+
+ self._doc_ids = None
+
+ # These are things we reference in the deprecated code, they are provided
+ # by the new effects code, but we want to keep this as a Mixin so these
+ # items will keep pylint happy and let use check our code as we write.
+ if not hasattr(self, 'svg'):
+ from .elements import SvgDocumentElement
+ self.svg = SvgDocumentElement()
+ if not hasattr(self, 'arg_parser'):
+ self.arg_parser = ArgumentParser()
+ if not hasattr(self, 'run'):
+ self.run = self.affect
+
+ @classmethod
+ def _deprecated(cls, name, msg=_('{} is deprecated and should be removed'), stack=3):
+ """Give the user a warning about their extension using a deprecated API"""
+ _deprecated(
+ msg.format('Effect.' + name, cls=cls.__module__ + '.' + cls.__name__),
+ stack=stack)
+
+ @property
+ def OptionParser(self):
+ self._deprecated(
+ 'OptionParser',
+ _('{} or `optparse` has been deprecated and replaced with `argparser`.'
+ 'You must change `self.OptionParser.add_option` to '
+ '`self.arg_parser.add_argument`; the arguments are similar.'))
+ return self
+
+ def add_option(self, *args, **kw):
+ # Convert type string into type method as needed
+ if 'type' in kw:
+ kw['type'] = {
+ 'string': str,
+ 'int': int,
+ 'float': float,
+ 'inkbool': inkex.utils.Boolean,
+ }.get(kw['type'])
+ if kw.get('action', None) == 'store':
+ # Default store action not required, removed.
+ kw.pop('action')
+ args = [arg for arg in args if arg != ""]
+ self.arg_parser.add_argument(*args, **kw)
+
+ def effect(self):
+ self._deprecated('effect', _('{} method is now a required method. It should '
+ 'be created on {cls}, even if it does nothing.'))
+
+ @property
+ def current_layer(self):
+ self._deprecated('current_layer',\
+ _('{} is now a method in the svg. Use `self.svg.get_current_layer()` instead.'))
+ return self.svg.get_current_layer()
+
+ @property
+ def view_center(self):
+ self._deprecated('view_center',\
+ _('{} is now a method in the svg. Use `self.svg.namedview.center` instead.'))
+ return self.svg.namedview.center
+
+ @property
+ def selected(self):
+ self._deprecated('selected', _('{} is now a dict in the svg. Use `self.svg.selected`.'))
+ return dict([(elem.get('id'), elem) for elem in self.svg.selected.values()])
+
+ @property
+ def doc_ids(self):
+ self._deprecated('doc_ids', _('{} is now a method in the svg '
+ 'document. Use `self.svg.get_ids()` instead.'))
+ if self._doc_ids is None:
+ self._doc_ids = dict.fromkeys(self.svg.get_ids())
+ return self._doc_ids
+
+ def getdocids(self):
+ self._deprecated('getdocids', _('Use `self.svg.get_ids()` instead of {} and `doc_ids`.'))
+ self._doc_ids = None
+ self.svg.ids.clear()
+
+ def getselected(self):
+ self._deprecated('getselected', _('{} has been removed'))
+
+ def getElementById(self, eid):
+ self._deprecated('getElementById',\
+ _('{} is now a method in the svg. Use `self.svg.getElementById(eid)` instead.'))
+ return self.svg.getElementById(eid)
+
+ def xpathSingle(self, xpath):
+ self._deprecated('xpathSingle', _('{} is now a new method in the svg '
+ 'document. Use `self.svg.getElement(path)` instead.`'))
+ return self.svg.getElement(xpath)
+
+ def getParentNode(self, node):
+ self._deprecated('getParentNode',\
+ _('{} is no longer in use. Use the lxml .getparent() method instead.'))
+ return node.getparent()
+
+ def getNamedView(self):
+ self._deprecated('getNamedView',\
+ _('{} is now a property of the svg. Use `self.svg.namedview` to access this element'))
+ return self.svg.namedview
+
+ def createGuide(self, posX, posY, angle):
+ from .elements import Guide
+ self._deprecated('createGuide',\
+ _('{} is now a method of the namedview element object. '
+ 'Use `self.svg.namedview.add(Guide().move_to(x, y, a))` instead'))
+ return self.svg.namedview.add(Guide().move_to(posX, posY, angle))
+
+ def affect(self, args=sys.argv[1:], output=True): # pylint: disable=dangerous-default-value
+ # We need a list as the default value to preserve backwards compatibility
+ self._deprecated('affect', _('{} is now `Effect.run()`. The `output` argument has changed.'))
+ self._args = args[-1:]
+ return self.run(args=args)
+
+ @property
+ def args(self):
+ self._deprecated('args', _('self.args[-1] is now self.options.input_file'))
+ return self._args
+
+ @property
+ def svg_file(self):
+ self._deprecated('svg_file', _('self.svg_file is now self.options.input_file'))
+ return self.options.input_file
+
+ def save_raw(self, ret):
+ # Derived class may implement "output()"
+ # Attention: 'cubify.py' implements __getattr__ -> hasattr(self, 'output') returns True
+ if hasattr(self.__class__, 'output'):
+ self._deprecated('output', 'Use `save()` or `save_raw()` instead.', stack=5)
+ return getattr(self, 'output')()
+ return inkex.base.InkscapeExtension.save_raw(self, ret)
+
+ def uniqueId(self, old_id, make_new_id=True):
+ self._deprecated('uniqueId', _('{} is now a method in the svg document. '
+ ' Use `self.svg.get_unique_id(old_id)` instead.'))
+ return self.svg.get_unique_id(old_id)
+
+ def getDocumentWidth(self):
+ self._deprecated('getDocumentWidth', _('{} is now a property of the svg '
+ 'document. Use `self.svg.width` instead.'))
+ return self.svg.get('width')
+
+ def getDocumentHeight(self):
+ self._deprecated('getDocumentHeight', _('{} is now a property of the svg '
+ 'document. Use `self.svg.height` instead.'))
+ return self.svg.get('height')
+
+ def getDocumentUnit(self):
+ self._deprecated('getDocumentUnit', _('{} is now a property of the svg '
+ 'document. Use `self.svg.unit` instead.'))
+ return self.svg.unit
+
+ def unittouu(self, string):
+ self._deprecated('unittouu', _('{} is now a method in the svg '
+ 'document. Use `self.svg.unittouu(str)` instead.'))
+ return self.svg.unittouu(string)
+
+ def uutounit(self, val, unit):
+ self._deprecated('uutounit', _('{} is now a method in the svg '
+ 'document. Use `self.svg.uutounit(value, unit)` instead.'))
+ return self.svg.uutounit(val, unit)
+
+ def addDocumentUnit(self, value):
+ self._deprecated('addDocumentUnit', _('{} is now a method in the svg '
+ 'document. Use `self.svg.add_unit(value)` instead.'))
+ return self.svg.add_unit(value)
+
+class Effect(SvgThroughMixin, DeprecatedEffect, InkscapeExtension):
+ """An Inkscape effect, takes SVG in and outputs SVG"""
+ pass
+
+def deprecate(func):
+ """Function decorator for deprecation functions which have a one-liner
+ equivalent in the new API. The one-liner has to passed as a string
+ to the decorator.
+
+ >>> @deprecate
+ >>> def someOldFunction(*args):
+ >>> '''Example replacement code someNewFunction('foo', ...)'''
+ >>> someNewFunction('foo', *args)
+
+ Or if the args API is the same:
+
+ >>> someOldFunction = deprecate(someNewFunction)
+
+ """
+
+ def _inner(*args, **kwargs):
+ _deprecated('{0.__module__}.{0.__name__} -> {0.__doc__}'.format(func), stack=2)
+ return func(*args, **kwargs)
+ _inner.__name__ = func.__name__
+ if func.__doc__:
+ _inner.__doc__ = "Deprecated -> " + func.__doc__
+ return _inner
+
+class DeprecatedDict(dict):
+ @deprecate
+ def __getitem__(self, key):
+ return super(DeprecatedDict, self).__getitem__(key)
+
+ @deprecate
+ def __iter__(self):
+ return super(DeprecatedDict, self).__iter__()
+
+# legacy inkex members
+
+class lazyproxy(object):
+ """Proxy, use as decorator on a function with provides the wrapped object.
+ The decorated function is called when a member is accessed on the proxy.
+ """
+ def __init__(self, getwrapped):
+ '''
+ :param getwrapped: Callable which returns the wrapped object
+ '''
+ self._getwrapped = getwrapped
+
+ def __getattr__(self, name):
+ return getattr(self._getwrapped(), name)
+
+ def __call__(self, *args, **kwargs):
+ return self._getwrapped()(*args, **kwargs)
+
+@lazyproxy
+def optparse():
+ _deprecated('inkex.optparse was removed, use "import optparse"', stack=3)
+ import optparse as wrapped
+ return wrapped
+
+@lazyproxy
+def etree():
+ _deprecated('inkex.etree was removed, use "from lxml import etree"', stack=3)
+ from lxml import etree as wrapped
+ return wrapped
+
+@lazyproxy
+def InkOption():
+ import optparse
+ class wrapped(optparse.Option):
+ TYPES = optparse.Option.TYPES + ("inkbool", )
+ TYPE_CHECKER = dict(optparse.Option.TYPE_CHECKER)
+ TYPE_CHECKER["inkbool"] = lambda _1, _2, v: str(v).capitalize() == 'True'
+ return wrapped
+
+@lazyproxy
+def localize():
+ _deprecated('inkex.localize was moved to inkex.localization.localize', stack=3)
+ from .localization import localize as wrapped
+ return wrapped
+
+def are_near_relative(a, b, eps):
+ _deprecated('inkex.are_near_relative was moved to '
+ 'inkex.units.are_near_relative', stack=2)
+ return inkex.units.are_near_relative(a, b, eps)
+
+def debug(what):
+ _deprecated('inkex.debug was moved to inkex.utils.debug', stack=2)
+ return inkex.utils.debug(what)
+
+# legacy inkex members <= 0.48.x
+
+def unittouu(string):
+ _deprecated('inkex.unittouu is now a method in the svg '
+ 'document. Use `self.svg.unittouu(str)` instead.', stack=2)
+ return inkex.units.convert_unit(string, 'px')
+
+# optparse.Values.ensure_value
+
+def ensure_value(self, attr, value):
+ _deprecated('Effect().options.ensure_value was removed', stack=2)
+ if getattr(self, attr, None) is None:
+ setattr(self, attr, value)
+ return getattr(self, attr)
+
+argparse.Namespace.ensure_value = ensure_value # type: ignore
+
+@deprecate
+def zSort(inNode, idList):
+ """self.svg.get_z_selected()"""
+ sortedList = []
+ theid = inNode.get("id")
+ if theid in idList:
+ sortedList.append(theid)
+ for child in inNode:
+ if len(sortedList) == len(idList):
+ break
+ sortedList += zSort(child, idList)
+ return sortedList
+
+class DeprecatedSvgMixin(object):
+ """Mixin which adds deprecated API elements to the SvgDocumentElement"""
+ @property
+ def selected(self):
+ """svg.selection"""
+ return self.selection
+
+ def set_selected(self, *ids):
+ """svg.selection.set(*ids)"""
+ return self.selection.set(*ids)
+
+ def get_z_selected(self):
+ """svg.selection.paint_order()"""
+ return self.selection.paint_order()
+
+ def get_selected(self, *types):
+ """svg.selection.filter(*types).values()"""
+ return self.selection.filter(*types).values()
+
+ def get_selected_or_all(self, *types):
+ """Set select_all = True in extension class"""
+ if not self.selection:
+ self.selection.set_all()
+ return self.selection.filter(*types)
+
+ def get_selected_bbox(self):
+ """selection.bounding_box()"""
+ return self.selection.bounding_box()
+
+ def get_first_selected(self, *types):
+ """selection.filter(*types).first() or [0] if you'd like an error"""
+ return self.selection.filter(*types).first()