GDQuest / krita-batch-exporter

A Free Krita plugin to batch export layers and groups with maximum flexibility. Scale, trim, export multiple copies of your layers...
GNU General Public License v3.0
319 stars 26 forks source link

Error when exporting selected layers or documents #22

Closed NathanLovato closed 5 years ago

NathanLovato commented 5 years ago

Trying to export anything by clicking All Layers or Selected Layers triggers an error. This happens only with the latest master, after the addition of the COA export.

Traceback:

TypeError
Python 3.6.7: /usr/bin/python3
Thu Mar 14 15:16:29 2019

A problem occurred in a Python script.  Here is the sequence of
function calls leading up to the error, in the order they occurred.

 /home/gdquest/.local/share/krita/pykrita/gdquest_art_tools/GDquestArtTools.py in exportSelectedLayers(cfg={'delimiters': OrderedDict([('assign', '='), ('separator', ',')]), 'done': {'msg': 'DONE: {}', 'timeout': 5000}, 'error': {'msg': 'ERROR: {}', 'timeout': 8000}, 'meta': {'c': [''], 'e': ['png'], 'm': [0], 'p': [''], 's': [100]}, 'outDir': 'export', 'rootPat': re.compile('^root'), 'sym': re.compile('\\W')}, statusBar=<PyQt5.QtWidgets.QStatusBar object>)
   62         it = map(partial(WNode, cfg), nodes)
   63         it = map(partial(flip(WNode.save), dirName), it)
   64         kickstart(it)
   65     except ValueError as e:
   66         msg, timeout = cfg['error']['msg'].format(e), cfg['error']['timeout']
global kickstart = <function kickstart>
it = <map object>

 /home/gdquest/.local/share/krita/pykrita/gdquest_art_tools/Utils/__init__.py in kickstart(it=<map object>)
    6 
    7 
    8 def kickstart(it):
    9     deque(it, maxlen=0)
   10 
global deque = <class 'collections.deque'>
it = <map object>
maxlen undefined

 /home/gdquest/.local/share/krita/pykrita/gdquest_art_tools/Utils/__init__.py in <lambda>(*a=('/home/gdquest/Repositories/flossy-gnu/art', <gdquest_art_tools.Infrastructure.WNode object>))
    3 
    4 def flip(f):
    5     return lambda *a: f(*reversed(a))
    6 
    7 
a = ('/home/gdquest/Repositories/flossy-gnu/art', <gdquest_art_tools.Infrastructure.WNode object>)
f = <function WNode.save>
builtinreversed = <class 'reversed'>

 /home/gdquest/.local/share/krita/pykrita/gdquest_art_tools/Infrastructure.py in save(self=<gdquest_art_tools.Infrastructure.WNode object>, dirname='/home/gdquest/Repositories/flossy-gnu/art')
  190         it = starmap(lambda i, e, p: (toJPEG(i) if e in ('jpg', 'jpeg') else i, p), it)
  191         it = starmap(lambda i, p: i.save(p), it)
  192         kickstart(it)
  193 
  194         return path.format(e=ext[0], m=margin[0], s=scale[0])
path = '/home/gdquest/Repositories/flossy-gnu/art/export/pillar_top_s{s:03d}_m{m:03d}.{e}'
path.format = <built-in method format of str object>
e undefined
ext = ['png']
m undefined
margin = [0]
s undefined
scale = <map object>
TypeError: 'map' object is not subscriptable
    __cause__ = None
    __class__ = <class 'TypeError'>
    __context__ = None
    __delattr__ = <method-wrapper '__delattr__' of TypeError object>
    __dict__ = {}
    __dir__ = <built-in method __dir__ of TypeError object>
    __doc__ = 'Inappropriate argument type.'
    __eq__ = <method-wrapper '__eq__' of TypeError object>
    __format__ = <built-in method __format__ of TypeError object>
    __ge__ = <method-wrapper '__ge__' of TypeError object>
    __getattribute__ = <method-wrapper '__getattribute__' of TypeError object>
    __gt__ = <method-wrapper '__gt__' of TypeError object>
    __hash__ = <method-wrapper '__hash__' of TypeError object>
    __init__ = <method-wrapper '__init__' of TypeError object>
    __init_subclass__ = <built-in method __init_subclass__ of type object>
    __le__ = <method-wrapper '__le__' of TypeError object>
    __lt__ = <method-wrapper '__lt__' of TypeError object>
    __ne__ = <method-wrapper '__ne__' of TypeError object>
    __new__ = <built-in method __new__ of type object>
    __reduce__ = <built-in method __reduce__ of TypeError object>
    __reduce_ex__ = <built-in method __reduce_ex__ of TypeError object>
    __repr__ = <method-wrapper '__repr__' of TypeError object>
    __setattr__ = <method-wrapper '__setattr__' of TypeError object>
    __setstate__ = <built-in method __setstate__ of TypeError object>
    __sizeof__ = <built-in method __sizeof__ of TypeError object>
    __str__ = <method-wrapper '__str__' of TypeError object>
    __subclasshook__ = <built-in method __subclasshook__ of type object>
    __suppress_context__ = False
    __traceback__ = <traceback object>
    args = ("'map' object is not subscriptable",)
    with_traceback = <built-in method with_traceback of TypeError object>

The above is a description of an error in a Python program.  Here is
the original traceback:

Traceback (most recent call last):
  File "/home/gdquest/.local/share/krita/pykrita/gdquest_art_tools/GDquestArtTools.py", line 64, in exportSelectedLayers
    kickstart(it)
  File "/home/gdquest/.local/share/krita/pykrita/gdquest_art_tools/Utils/__init__.py", line 9, in kickstart
    deque(it, maxlen=0)
  File "/home/gdquest/.local/share/krita/pykrita/gdquest_art_tools/Utils/__init__.py", line 5, in <lambda>
    return lambda *a: f(*reversed(a))
  File "/home/gdquest/.local/share/krita/pykrita/gdquest_art_tools/Infrastructure.py", line 194, in save
    return path.format(e=ext[0], m=margin[0], s=scale[0])
TypeError: 'map' object is not subscriptable
razcore-rad commented 5 years ago

I missed this. This happens because of:

return path.format(e=ext[0], m=margin[0], s=scale[0])

@Larpon after thinking about it maybe this isn't the right way to do it. What happens if you use c= metadata with multiple s= values say? You'd end up exporting for COA the same file multiple times but returning the same filename/file path if it wouldn't give an error. So your COA module would use incorrect paths.

We need to think a bit more how c= should interact with the other metadata. Should it ignore it, at least margin/scale? (m/s) should it treat it differently? Plus there's this error when not using c=, but the other metadata because I'm creating map objects which can't be indexed with eg. mab_obj[0].

For now @NathanLovato, for your own use, you can just comment out that line from Infrastructure.py or downgrade to the previous commit.

larpon commented 5 years ago

@razcore-art - well right now the support for c= can actually be removed completely. I put it there to make it ready for sheet support. The sheet support feature could be made to support margins and scaling. But it'll have to be a function you run after using WNode.save(). Then find the exported files and combine them into a sheet, collect the meta-data and then delete(?) the exported files used in the sheet and finally join the meta-data with the final json result

I particularly find this section a little frustrating to work out and expand.

larpon commented 5 years ago

Quick fix in #23