Commits

sirex committed cd4d124 Draft

Added support form zip files with leading first folder, that can be removed with strip flag.

  • Participants
  • Parent commits acb3ac9

Comments (0)

Files changed (1)

 #!/usr/bin/env python3
 
 import os
+import os.path
 import re
 
-from os.path import exists, expanduser, join, splitext, isdir
+from os.path import exists, expanduser, join, isdir
 from subprocess import check_call
 from urllib.request import urlretrieve, urlopen
 from zipfile import ZipFile
 PATHOGEN_URL = ('https://raw.github.com/tpope/vim-pathogen'
                 '/HEAD/autoload/pathogen.vim')
 
-PLUGIN_RE = re.compile(r'" plugin: (\S+) (ht|git|svn|vim|zip) (\S+)')
+PLUGIN_RE = re.compile(r'" plugin: (\S+) ((ht|git|svn|vim|zip)\S*) (\S+)')
 
 
 def sh(cmd, *args, **kwargs):
         os.makedirs(BUNDLE_DIR)
 
 
+resolved = lambda x: os.path.realpath(os.path.abspath(x))
+
+
+def _badpath(path, base):
+    return not resolved(os.path.join(base, path)).startswith(base)
+
+
+def lstrippath(base, path):
+    path = path[len(base) + 1:]
+    items = path.split(os.path.sep)
+    items.pop(0)
+    return os.path.join(base, *items)
+
+
+def unzip(zipfile, base, strip=False):
+    with ZipFile(zipfile) as f:
+        for filename in f.namelist():
+            path = resolved(os.path.join(base, filename))
+            if (not filename.endswith('/') and
+                path.startswith(base + os.path.sep)):
+                if strip:
+                    path = lstrippath(base, path)
+                if len(path) > len(base):
+                    path_dir = os.path.dirname(path)
+                    if not os.path.exists(path_dir):
+                        os.makedirs(path_dir)
+                    zf = f.open(filename)
+                    with open(path, 'wb') as rf:
+                        rf.write(zf.read())
+
+
 class Plugin(object):
-    def __init__(self, name, handler, path):
+    def __init__(self, name, handler, path, kwargs):
         self.name = name
         self.handler = handler
         self.path = path
+        self.kwargs = kwargs
         self.run = []
 
     def handle_hg(self):
     def handle_git(self):
         sh(['git', 'clone', self.path, self.name])
 
-    def handle_vim(self):
+    def handle_vim(self, strip=False):
         with urlopen(self.path) as f:
             content = f.read().decode('ISO-8859-1')
         m = re.search(r'download_script\.php\?src_id=\d+', content)
         if m is None:
             raise Exception("Can't find vim script to download.")
         filename, headers = urlretrieve('http://www.vim.org/scripts/' + m.group(0))
-        ext = splitext(headers.get_filename())[1].replace('.', '')
-        with ZipFile(filename) as f:
-            f.extractall(self.name)
+        base = resolved(self.name)
+        unzip(filename, base, strip=strip)
 
     def get_handler(self):
         return getattr(self, 'handle_%s' % self.handler)
         else:
             print('plugin: %s installing...' % self.name)
             handler = self.get_handler()
-            handler()
+            handler(**self.kwargs)
 
             if self.run:
                 cwd = os.getcwd()
             print('  ... installed.\n')
 
 
+def parse_kwargs(s):
+    """
+
+    >>> parse_kwargs('vim')
+    ('vim', {})
+    >>> parse_kwargs('vim|strip|key=val')
+    ('vim', {'key': 'val', 'strip': True})
+
+    """
+    if '|' not in s:
+        return s, {}
+
+    spl = s.split('|')
+    name = spl.pop(0)
+    kwargs = {}
+    for item in spl:
+        if '=' in item:
+            key, val = item.split('=', 1)
+        else:
+            key, val = item, True
+        kwargs[key] = val
+    return name, kwargs
+
+
 def get_plugins():
     plugins = []
     pathogen_not_found = True
             if line.startswith('" plugin: '):
                 m = PLUGIN_RE.match(line)
                 if m:
-                    name, handler, path = m.groups()
-                    plugin = Plugin(name, handler, path)
+                    name, handler, x, path = m.groups()
+                    handler, kwargs = parse_kwargs(handler)
+                    plugin = Plugin(name, handler, path, kwargs)
                     plugins.append(plugin)
 
             elif line.startswith('" run: ') and plugin is not None: