summaryrefslogtreecommitdiffstats
path: root/share/extensions/media_zip.py
diff options
context:
space:
mode:
Diffstat (limited to 'share/extensions/media_zip.py')
-rwxr-xr-xshare/extensions/media_zip.py184
1 files changed, 184 insertions, 0 deletions
diff --git a/share/extensions/media_zip.py b/share/extensions/media_zip.py
new file mode 100755
index 0000000..9881bff
--- /dev/null
+++ b/share/extensions/media_zip.py
@@ -0,0 +1,184 @@
+#!/usr/bin/env python
+# coding=utf-8
+#
+# Copyright (C) 2005 Pim Snel, pim@lingewoud.com
+# Copyright (C) 2008 Aaron Spike, aaron@ekips.org
+# Copyright (C) 2011 Nicolas Dufour, nicoduf@yahoo.fr
+#
+# * Fix for a bug related to special characters in the path (LP #456248).
+# * Fix for Windows support (LP #391307 ).
+# * Font list and image directory features.
+#
+# this is the first Python script ever created
+# its based on embedimage.py
+#
+# 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.
+#
+# TODOs
+# - fix bug: not saving existing .zip after a Collect for Output is run
+# this bug occurs because after running an effect extension 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 extension
+# - consider switching to lzma in order to allow cross platform compression with no encoding problem...
+#
+"""
+An extension which collects all images to the documents directory and
+creates a zip archive containing all images and the document
+"""
+
+import os
+import shutil
+import tempfile
+import zipfile
+
+import inkex
+from inkex import TextElement, Tspan, FlowRoot, FlowPara, FlowSpan
+
+try: # PY2
+ from urllib import url2pathname
+ from urlparse import urlparse
+except ImportError: # PY3
+ from urllib.parse import urlparse
+ from urllib.request import url2pathname
+
+ENCODING = "cp437" if os.name == 'nt' else "latin-1"
+
+class CompressedMedia(inkex.OutputExtension):
+ """Output a compressed file"""
+ def add_arguments(self, pars):
+ pars.add_argument("--image_dir", help="Image directory")
+ pars.add_argument("--font_list", type=inkex.Boolean, help="Add font list")
+
+ def collect_images(self, docname, z):
+ """
+ Collects all images in the document
+ and copy them to the temporary directory.
+ """
+ imgdir = self.options.image_dir
+
+ for node in self.svg.xpath('//svg:image'):
+ xlink = node.get('xlink:href')
+ if xlink[:4] != 'data':
+ absref = node.get('sodipodi:absref')
+ url = urlparse(xlink)
+ href = url2pathname(url.path)
+
+ if href is not None and os.path.isfile(href):
+ absref = os.path.realpath(href)
+
+ image_path = os.path.join(imgdir, os.path.basename(absref))
+
+ if os.path.isfile(absref):
+ shutil.copy(absref, self.tmp_dir)
+ z.write(absref, image_path.encode(ENCODING))
+ 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), image_path.encode(ENCODING))
+ else:
+ inkex.errormsg('Could not locate file: %s' % absref)
+
+ node.set('xlink:href', image_path)
+
+ def collect_svg(self, docstripped, z):
+ """
+ Copy SVG document to the temporary directory
+ and add it to the temporary compressed file
+ """
+ dst_file = os.path.join(self.tmp_dir, docstripped)
+ with open(dst_file, 'wb') as stream:
+ self.document.write(stream)
+ z.write(dst_file, docstripped + '.svg')
+
+ def is_text(self, node):
+ """
+ Returns true if the tag in question is an element that
+ can hold text.
+ """
+ return isinstance(node, (TextElement, Tspan, FlowRoot, FlowPara, FlowSpan))
+
+ def get_fonts(self, node):
+ """
+ Given a node, returns a list containing all the fonts that
+ the node is using.
+ """
+ fonts = []
+ s = ''
+ if 'style' in node.attrib:
+ s = dict(inkex.Style.parse_str(node.attrib['style']))
+ if not s:
+ return fonts
+
+ if 'font-family' in s:
+ if 'font-weight' in s:
+ fonts.append(s['font-family'] + ' ' + s['font-weight'])
+ else:
+ fonts.append(s['font-family'])
+ elif '-inkscape-font-specification' in s:
+ fonts.append(s['-inkscape-font-specification'])
+ return fonts
+
+ def list_fonts(self, z):
+ """
+ Walks through nodes, building a list of all fonts found, then
+ reports to the user with that list.
+ Based on Craig Marshall's replace_font.py
+ """
+ nodes = []
+ items = self.document.getroot().getiterator()
+ nodes.extend(filter(self.is_text, items))
+ fonts_found = []
+ for node in nodes:
+ for f in self.get_fonts(node):
+ if not f in fonts_found:
+ fonts_found.append(f)
+ findings = sorted(fonts_found)
+ # Write list to the temporary compressed file
+ filename = 'fontlist.txt'
+ dst_file = os.path.join(self.tmp_dir, filename)
+ with open(dst_file, 'w') as stream:
+ if len(findings) == 0:
+ stream.write("Didn't find any fonts in this document/selection.")
+ else:
+ if len(findings) == 1:
+ stream.write("Found the following font only: %s" % findings[0])
+ else:
+ stream.write("Found the following fonts:\n%s" % '\n'.join(findings))
+ z.write(dst_file, filename)
+
+ def save(self, stream):
+ docname = self.svg.get('sodipodi:docname')
+
+ if docname is None:
+ docname = self.options.input_file
+
+ # TODO: replace whatever extension
+ docstripped = os.path.basename(docname.replace('.zip', ''))
+ docstripped = docstripped.replace('.svg', '')
+ docstripped = docstripped.replace('.svgz', '')
+
+ # Create os temp dir
+ self.tmp_dir = tempfile.mkdtemp()
+
+ # Create destination zip in same directory as the document
+ with zipfile.ZipFile(stream, 'w') as z:
+ self.collect_images(docname, z)
+ self.collect_svg(docstripped, z)
+ if self.options.font_list:
+ self.list_fonts(z)
+
+if __name__ == '__main__':
+ CompressedMedia().run()