Code

implemented proper error checking
[inkscape.git] / share / extensions / svg_and_media_zip_output.py
index 74311b4315c4a97e5abd0e49ee7e74ad296c979f..640c9ede4c1979dbc3818bd595b3243cefb31ed4 100644 (file)
@@ -1,4 +1,4 @@
-#! /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
@@ -23,7 +23,8 @@ 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.5 (Nicolas Dufour, nicoduf@yahoo.fr)
+    Fix a bug related to special caracters in the path (LP #456248).
 
 TODO
 - fix bug: not saving existing .zip after a Collect for Output is run
@@ -31,81 +32,108 @@ TODO
      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
+- consider switching to lzma in order to allow cross platform compression with no encoding problem...
 """
 
-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
+import gettext
+_ = gettext.gettext
 
-class MyEffect(inkex.Effect):
+class SVG_and_Media_ZIP_Output(inkex.Effect):
     def __init__(self):
         inkex.Effect.__init__(self)
+        if os.name == 'nt':
+            self.encoding = "cp437"
+        else:
+            self.encoding = "latin-1"     
 
     def output(self):
-        pass
+        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()
 
-        docbase = ttmp_orig.get(inkex.addNS('docbase',u'sodipodi'),'')
         docname = ttmp_orig.get(inkex.addNS('docname',u'sodipodi'))
-
-        orig_tmpfile = sys.argv[1]
+        if docname is None: docname = self.args[-1]
 
         #create os temp dir
-        tmp_dir = tempfile.mkdtemp()
-        
-        # create destination zip in same directory as the document
-        z = zipfile.ZipFile(tmp_dir + os.path.sep + docname + '.zip', 'w')    
+        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, tmp_dir, docname, z)
+            self.collectAndZipImages(node, docname, z)
 
         ##copy tmpdoc to tempdir
-        dst_file = os.path.join(tmp_dir, docstripped)
+        dst_file = os.path.join(self.tmp_dir, docstripped)
         stream = open(dst_file,'w')
-    
+
         self.document.write(stream)
-        
+
         stream.close()
-        
-        z.write(dst_file.encode("latin-1"),docstripped.encode("latin-1")+'.svg') 
-        z.close()
 
-        out = open(tmp_dir + os.path.sep + docname + '.zip','r')
-        sys.stdout.write(out.read())
-        out.close() 
-        
-        shutil.rmtree(tmp_dir)
+        z.write(dst_file,docstripped.encode(self.encoding)+'.svg')
+
+        z.close()
 
-    def collectAndZipImages(self, node, tmp_dir, docname, z):
+    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.url2pathname(url.path)
+            
+            if (href != None):
+                absref=os.path.realpath(href)
+
+            absref=unicode(absref, "utf-8")
+
             if (os.path.isfile(absref)):
-                shutil.copy(absref,tmp_dir)
-                z.write(absref.encode("latin-1"),os.path.basename(absref).encode("latin-1"))
-            elif (os.path.isfile(tmp_dir + os.path.sep + absref)):
+                shutil.copy(absref, self.tmp_dir)
+                z.write(absref, os.path.basename(absref).encode(self.encoding))
+            elif (os.path.isfile(os.path.join(self.tmp_dir, absref))):
                 #TODO: please explain why this clause is necessary
-                shutil.copy(tmp_dir + os.path.sep + absref,tmp_dir)
-                z.write(tmp_dir + os.path.sep + absref.encode("latin-1"),os.path.basename(absref).encode("latin-1"))
+                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(self.encoding))
             else:
-                inkex.debug('Could not locate file: %s' % absref)
+                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))
 
-            
-e = MyEffect()
-e.affect()
+
+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
+# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 fileencoding=utf-8 textwidth=99