Code

patch by Adib for 406470
[inkscape.git] / share / extensions / svg_and_media_zip_output.py
index 09ecb5f99d596072ef5c977de9e8683b96cc2214..341de728b94b4738d67aa6c0282ab8045abe59c0 100644 (file)
@@ -1,10 +1,11 @@
-#!/usr/bin/env python 
+#! /usr/bin/env python
 """
 svg_and_media_zip_output.py
-An extention which collects all images to the documents directory and 
+An extention which collects all images to the documents directory and
 creates a zip archive containing all images and the document
 
 Copyright (C) 2005 Pim Snel, pim@lingewoud.com
+Copyright (C) 2008 Aaron Spike, aaron@ekips.org
 this is  the first Python script  ever created
 its based on embedimage.py
 
@@ -22,102 +23,114 @@ 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
-Version 0.3
+Version 0.4 (Nicolas Dufour, nicoduf@yahoo.fr)
+  fix a coding bug: now use UTF-8 to save filenames in the archive.
+  fix xlink href parsing (now a real URL in 0.47).
+  fix Win32 stdout \r\r\n bug (stdout now set to bin mode).
+  fix a double .svg extension bug (added svg and svgz in the docstripped extensions).
 
 TODO
 - fix bug: not saving existing .zip after a Collect for Output is run
-        this bug occurs because after running an effect extention the inkscape:output_extension is reset to svg.inkscape
-        the file name is still xxx.zip. after saving again the file xxx.zip is written with a plain .svg which 
-        looks like a corrupt zip
+     this bug occurs because after running an effect extention the inkscape:output_extension is reset to svg.inkscape
+     the file name is still xxx.zip. after saving again the file xxx.zip is written with a plain .svg which
+     looks like a corrupt zip
 - maybe add better extention
 """
 
-import inkex, os.path
-import os
+import inkex
+import urlparse
+import urllib
+import os, os.path
 import string
 import zipfile
 import shutil
 import sys
 import tempfile
-
-class MyEffect(inkex.Effect):
-       def __init__(self):
-               inkex.Effect.__init__(self)
-
-               self.documentDst=None
-
-       def parseTmp(self,file=None):
-               """Parse document in specified file or on stdin"""
-               reader = inkex.xml.dom.ext.reader.Sax2.Reader()
-               try:
-                       try:
-                               stream = open(file,'r')
-                       except:
-                               stream = open(self.args[-1],'r')
-               except:
-                       stream = sys.stdin
-               self.documentDst = reader.fromStream(stream)
-               stream.close()
-
-       def output(self):
-               pass
-
-       def effect(self):
-               
-               #get needed info from orig document
-               ctx_orig = inkex.xml.xpath.Context.Context(self.document,processorNss=inkex.NSS)
-
-               ttmp_orig = inkex.xml.xpath.Evaluate('/svg',self.document, context=ctx_orig)
-               
-               docbase = ttmp_orig[0].attributes.getNamedItemNS(inkex.NSS[u'sodipodi'],'docbase')
-               docname = ttmp_orig[0].attributes.getNamedItemNS(inkex.NSS[u'sodipodi'],'docname')
-
-               orig_tmpfile = sys.argv[1]
-
-               # create destination zip in same directory as the document
-               z = zipfile.ZipFile(docbase.value + '/'+ docname.value + '.zip', 'w')   
-
-               #create os temp dir
-               tmp_dir = tempfile.mkdtemp()
-
-               #fixme replace whatever extention
-               docstripped = docname.value.replace('.zip', '')
-       
-               #read tmpdoc and copy all images to temp dir
-               for node in inkex.xml.xpath.Evaluate('//image',self.document, context=ctx_orig):
-                       self.collectAndZipImages(node, tmp_dir, docname, z)
-
-               ##copy tmpdoc to tempdir
-               dst_file = os.path.join(tmp_dir, docstripped)
-               stream = open(dst_file,'w')
-       
-               inkex.xml.dom.ext.Print(self.document,stream)
-               
-               stream.close()
-               
-               z.write(dst_file.encode("latin-1"),docstripped.encode("latin-1")+'.svg') 
-               z.close()
-
-               shutil.move(docbase.value + '/'+ docname.value + '.zip',docbase.value + '/'+ docname.value)
-               
-               shutil.rmtree(tmp_dir)
-
-       def collectAndZipImages(self, node, tmp_dir, docname, z):
-               xlink = node.attributes.getNamedItemNS(inkex.NSS[u'xlink'],'href')
-               if (xlink.value[:4]!='data'):
-                       absref=node.attributes.getNamedItemNS(inkex.NSS[u'sodipodi'],'absref')
-
-                       if (os.path.isfile(absref.value)):
-                               shutil.copy(absref.value,tmp_dir)
-                               z.write(absref.value.encode("latin-1"),os.path.basename(absref.value).encode("latin-1"))
-
-                       elif (os.path.isfile(tmp_dir + '/' + absref.value)):
-                               shutil.copy(tmp_dir + '/' + absref.value,tmp_dir)
-                               z.write(tmp_dir + '/' + absref.value.encode("latin-1"),os.path.basename(absref.value).encode("latin-1"))
-
-                       xlink.value = os.path.basename(absref.value)
-                       absref.value = os.path.basename(absref.value)
-
-                       
-e = MyEffect()
-e.affect()
+import gettext
+_ = gettext.gettext
+
+class SVG_and_Media_ZIP_Output(inkex.Effect):
+    def __init__(self):
+        inkex.Effect.__init__(self)
+
+    def output(self):
+        out = open(self.zip_file,'rb')
+        if os.name == 'nt':
+            try:
+                import msvcrt
+                msvcrt.setmode(1, os.O_BINARY)
+            except:
+                pass
+        sys.stdout.write(out.read())
+        out.close()
+        self.clear_tmp()
+
+    def clear_tmp(self):
+        shutil.rmtree(self.tmp_dir)
+
+    def effect(self):
+        ttmp_orig = self.document.getroot()
+
+        docname = ttmp_orig.get(inkex.addNS('docname',u'sodipodi'))
+        if docname is None: docname = self.args[-1]
+
+        #create os temp dir
+        self.tmp_dir = tempfile.mkdtemp()
+
+        #fixme replace whatever extention
+        docstripped = docname.replace('.zip', '')
+        docstripped = docstripped.replace('.svg', '')
+        docstripped = docstripped.replace('.svgz', '')
+        
+        # create destination zip in same directory as the document
+        self.zip_file = os.path.join(self.tmp_dir, docstripped) + '.zip'
+        z = zipfile.ZipFile(self.zip_file, 'w')
+
+        #read tmpdoc and copy all images to temp dir
+        for node in self.document.xpath('//svg:image', namespaces=inkex.NSS):
+            self.collectAndZipImages(node, docname, z)
+
+        ##copy tmpdoc to tempdir
+        dst_file = os.path.join(self.tmp_dir, docstripped)
+        stream = open(dst_file,'w')
+
+        self.document.write(stream)
+
+        stream.close()
+
+        z.write(dst_file,docstripped.encode("utf_8")+'.svg')
+
+        z.close()
+
+    def collectAndZipImages(self, node, docname, z):
+        xlink = node.get(inkex.addNS('href',u'xlink'))
+        if (xlink[:4]!='data'):
+            absref=node.get(inkex.addNS('absref',u'sodipodi'))
+            url=urlparse.urlparse(xlink)
+            href=urllib.unquote(url.path)
+            if os.name == 'nt' and href[0] == '/':
+                href = href[1:]
+            if (href != None):
+                absref=os.path.realpath(href)
+
+            if (os.path.isfile(absref)):
+                shutil.copy(absref, self.tmp_dir)
+                z.write(absref, os.path.basename(absref).encode("utf_8"))
+            elif (os.path.isfile(os.path.join(self.tmp_dir, absref))):
+                #TODO: please explain why this clause is necessary
+                shutil.copy(os.path.join(self.tmp_dir, absref), self.tmp_dir)
+                z.write(os.path.join(self.tmp_dir, absref),
+                        os.path.basename(absref).encode("utf_8"))
+            else:
+                inkex.errormsg(_('Could not locate file: %s') % absref)
+
+            node.set(inkex.addNS('href',u'xlink'),os.path.basename(absref))
+            node.set(inkex.addNS('absref',u'sodipodi'),os.path.basename(absref))
+
+
+if __name__ == '__main__':   #pragma: no cover
+    e = SVG_and_Media_ZIP_Output()
+    e.affect()
+
+
+# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99