Code

Fix for bug #391307 (SVG and media output not working on Windows).
[inkscape.git] / share / extensions / svg_and_media_zip_output.py
1 #! /usr/bin/env python
2 """
3 svg_and_media_zip_output.py
4 An extention which collects all images to the documents directory and
5 creates a zip archive containing all images and the document
7 Copyright (C) 2005 Pim Snel, pim@lingewoud.com
8 Copyright (C) 2008 Aaron Spike, aaron@ekips.org
9 this is  the first Python script  ever created
10 its based on embedimage.py
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 Version 0.4 (Nicolas Dufour, nicoduf@yahoo.fr)
27   fix a coding bug: now use UTF-8 to save filenames in the archive.
28   fix xlink href parsing (now a real URL in 0.47).
29   fix Win32 stdout \r\r\n bug (stdout now set to bin mode).
30   fix a double .svg extension bug (added svg and svgz in the docstripped extensions).
32 TODO
33 - fix bug: not saving existing .zip after a Collect for Output is run
34      this bug occurs because after running an effect extention the inkscape:output_extension is reset to svg.inkscape
35      the file name is still xxx.zip. after saving again the file xxx.zip is written with a plain .svg which
36      looks like a corrupt zip
37 - maybe add better extention
38 """
40 import inkex
41 import urlparse
42 import urllib
43 import os, os.path
44 import string
45 import zipfile
46 import shutil
47 import sys
48 import tempfile
49 import gettext
50 _ = gettext.gettext
52 class SVG_and_Media_ZIP_Output(inkex.Effect):
53     def __init__(self):
54         inkex.Effect.__init__(self)
56     def output(self):
57         out = open(self.zip_file,'rb')
58         if os.name == 'nt':
59             try:
60                 import msvcrt
61                 msvcrt.setmode(1, os.O_BINARY)
62             except:
63                 pass
64         sys.stdout.write(out.read())
65         out.close()
66         self.clear_tmp()
68     def clear_tmp(self):
69         shutil.rmtree(self.tmp_dir)
71     def effect(self):
72         ttmp_orig = self.document.getroot()
74         docname = ttmp_orig.get(inkex.addNS('docname',u'sodipodi'))
75         if docname is None: docname = self.args[-1]
77         #create os temp dir
78         self.tmp_dir = tempfile.mkdtemp()
80         #fixme replace whatever extention
81         docstripped = docname.replace('.zip', '')
82         docstripped = docstripped.replace('.svg', '')
83         docstripped = docstripped.replace('.svgz', '')
84         
85         # create destination zip in same directory as the document
86         self.zip_file = os.path.join(self.tmp_dir, docstripped) + '.zip'
87         z = zipfile.ZipFile(self.zip_file, 'w')
89         #read tmpdoc and copy all images to temp dir
90         for node in self.document.xpath('//svg:image', namespaces=inkex.NSS):
91             self.collectAndZipImages(node, docname, z)
93         ##copy tmpdoc to tempdir
94         dst_file = os.path.join(self.tmp_dir, docstripped)
95         stream = open(dst_file,'w')
97         self.document.write(stream)
99         stream.close()
101         z.write(dst_file,docstripped.encode("utf_8")+'.svg')
103         z.close()
105     def collectAndZipImages(self, node, docname, z):
106         xlink = node.get(inkex.addNS('href',u'xlink'))
107         if (xlink[:4]!='data'):
108             absref=node.get(inkex.addNS('absref',u'sodipodi'))
109             url=urlparse.urlparse(xlink)
110             href=urllib.unquote(url.path)
111             if os.name == 'nt' and href[0] == '/':
112                 href = href[1:]
113             if (href != None):
114                 absref=os.path.realpath(href)
116             if (os.path.isfile(absref)):
117                 shutil.copy(absref, self.tmp_dir)
118                 z.write(absref, os.path.basename(absref).encode("utf_8"))
119             elif (os.path.isfile(os.path.join(self.tmp_dir, absref))):
120                 #TODO: please explain why this clause is necessary
121                 shutil.copy(os.path.join(self.tmp_dir, absref), self.tmp_dir)
122                 z.write(os.path.join(self.tmp_dir, absref),
123                         os.path.basename(absref).encode("utf_8"))
124             else:
125                 inkex.errormsg(_('Could not locate file: %s') % absref)
127             node.set(inkex.addNS('href',u'xlink'),os.path.basename(absref))
128             node.set(inkex.addNS('absref',u'sodipodi'),os.path.basename(absref))
131 if __name__ == '__main__':   #pragma: no cover
132     e = SVG_and_Media_ZIP_Output()
133     e.affect()
136 # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99