Commits

Kirill Simonov committed a26d463

Download vendor packages during installation.

  • Participants
  • Parent commits 2f71efd

Comments (0)

Files changed (6)

 build
 vm-build
 external
+vendor
 sandbox
 include README LICENSE NEWS AUTHORS
 
 # Package resources.
-recursive-include src *.html *.css *.js *.png
+recursive-include src *.html *.css *.js *.png *.svg README README.* LICENSE LICENSE.*
 
 # Generated HTML documentation and MAN pages.
 recursive-include doc/html *
 
 
 from setuptools import setup, find_packages
-import os.path, re
+from setuptools.command.develop import develop as setuptools_develop
+from distutils.command.build import build as setuptools_build
+from distutils.cmd import Command
+from distutils.dir_util import remove_tree
+from distutils import log
+import os, os.path, re, hashlib, urllib2, cStringIO, zipfile
 
 
 def get_version():
     ]
 
 
+def get_vendors():
+    # Vendor packages to download `(url, md5, target)`.
+    return [
+        ('http://code.jquery.com/jquery-1.6.4.min.js',
+         '9118381924c51c89d9414a311ec9c97f',
+         'src/htsql/tweak/shell/vendor/jquery-1.6.4'),
+        ('http://codemirror.net/codemirror-2.13.zip',
+         '211de80f62d67c2475cd189d295191ff',
+         'src/htsql/tweak/shell/vendor/codemirror-2.13'),
+    ]
+
+
+class build_vendor(Command):
+    # Download vendor packages.
+
+    user_options = []
+
+    def initialize_options(self):
+        pass
+
+    def finalize_options(self):
+        pass
+
+    def run(self):
+        build_cmd = self.get_finalized_command('build')
+        for url, md5_hash, target in get_vendors():
+            if os.path.exists(target):
+                continue
+            log.info("downloading vendor package '%s'" % url)
+            stream = urllib2.urlopen(url)
+            data = stream.read()
+            stream.close()
+            assert hashlib.md5(data).hexdigest() == md5_hash
+            build_dir = os.path.join(build_cmd.build_base,
+                                     os.path.basename(target))
+            if os.path.exists(build_dir):
+                remove_tree(build_dir)
+            os.mkdir(build_dir)
+            if url.endswith('.zip'):
+                archive = zipfile.ZipFile(cStringIO.StringIO(data))
+                entries = archive.infolist()
+                assert entries
+                common = entries[0].filename
+                if not (common.endswith('/') and
+                        all(entry.filename.startswith(common)
+                            for entry in entries)):
+                    common = ''
+                for entry in entries:
+                    filename = entry.filename[len(common):]
+                    if filename.startswith('/'):
+                        filename = filename[1:]
+                    if not filename:
+                        continue
+                    filename = os.path.join(build_dir, filename)
+                    if filename.endswith('/'):
+                        os.mkdir(filename)
+                    else:
+                        stream = open(filename, 'wb')
+                        stream.write(archive.read(entry))
+                        stream.close()
+            else:
+                filename = os.path.join(build_dir,
+                                        os.path.basename(url))
+                stream = open(filename, 'wb')
+                stream.write(data)
+                stream.close()
+            target_base = os.path.dirname(target)
+            if not os.path.exists(target_base):
+                os.makedirs(target_base)
+            os.rename(build_dir, target)
+
+
+class build(setuptools_build):
+
+    sub_commands = [('build_vendor', None)] + setuptools_build.sub_commands
+
+
+class develop(setuptools_develop):
+
+    def install_for_development(self):
+        self.run_command('build_vendor')
+        setuptools_develop.install_for_development(self)
+
+
 if __name__ == '__main__':
     setup(name="HTSQL",
           version=get_version(),
           entry_points={
               'console_scripts': ['htsql-ctl = htsql.ctl:main'],
               'htsql.routines': get_routines(),
-              'htsql.addons': get_addons()})
+              'htsql.addons': get_addons()},
+          cmdclass={
+              'build_vendor': build_vendor,
+              'build': build,
+              'develop': develop})
 
 

File src/htsql/tweak/resource/locate.py

         return Resource(name, data, etag=etag)
 
 
-class LocateRemote(Locate):
-
-    url = None
-    md5 = None
-    cache = None
-    is_zip = False
-
-    def __init__(self, path):
-        super(LocateRemote, self).__init__(path)
-        self.init_repository()
-
-    def init_repository(self):
-        userdir = os.path.expanduser('~')
-        staticdir = os.path.join(userdir, '.htsql')
-        resourcedir = os.path.join(staticdir, 'resource')
-        cachedir = os.path.join(resourcedir, '%s.%s' % (self.cache, self.md5))
-        if not os.path.exists(cachedir):
-            addon = context.app.tweak.resource
-            with addon.lock:
-                if not os.path.exists(staticdir):
-                    os.mkdir(staticdir, 0700)
-                if not os.path.exists(resourcedir):
-                    os.mkdir(resourcedir)
-                if not os.path.exists(cachedir):
-                    self.init_cache(cachedir)
-        self.repository = cachedir
-
-    def init_cache(self, cachedir):
-        stream = urllib2.urlopen(self.url)
-        data = stream.read()
-        stream.close()
-        assert hashlib.md5(data).hexdigest() == self.md5
-        filename = os.path.join(cachedir, os.path.basename(self.url))
-        if not self.is_zip:
-            os.mkdir(cachedir)
-            stream = open(filename, 'wb')
-            stream.write(data)
-            stream.close()
-        else:
-            self.unpack(cachedir, data)
-
-    def unpack(self, cachedir, data):
-        archive = zipfile.ZipFile(cStringIO.StringIO(data))
-        entries = archive.infolist()
-        if not entries:
-            return
-        common = entries[0].filename
-        if not (common.endswith('/') and
-                all(entry.filename.startswith(common)
-                    for entry in entries)):
-            common = ''
-        os.mkdir(cachedir)
-        for entry in entries:
-            filename = entry.filename[len(common):]
-            if filename.startswith('/'):
-                filename = filename[1:]
-            if not filename:
-                continue
-            filename = os.path.join(cachedir, filename)
-            if filename.endswith('/'):
-                os.mkdir(filename)
-            else:
-                stream = open(filename, 'wb')
-                stream.write(archive.read(entry))
-                stream.close()
-
-    def __call__(self):
-        filename = os.path.join(self.repository, self.suffix)
-        if not os.path.isfile(filename):
-            return super(LocateRemote, self).__call__()
-        name = os.path.basename(filename)
-        stream = open(filename)
-        data = stream.read()
-        stream.close()
-        stat = os.stat(filename)
-        etag = "%s-%s" % (int(stat.st_mtime), stat.st_size)
-        return Resource(name, data, etag=etag)
-
-
 locate = Locate.__invoke__
 
 

File src/htsql/tweak/shell/locate.py

 
 
 from ...core.adapter import call
-from ..resource.locate import LocatePackage, LocateRemote
+from ..resource.locate import LocatePackage
 
 
 class LocateShell(LocatePackage):
     directory = 'static'
 
 
-class LocateJQuery(LocateRemote):
+class LocateJQuery(LocatePackage):
 
-    call('/shell/external/jquery/')
-    url = 'http://code.jquery.com/jquery-1.6.4.min.js'
-    md5 = '9118381924c51c89d9414a311ec9c97f'
-    cache = 'jquery-1.6.4'
+    call('/shell/vendor/jquery/')
+    package = __name__
+    directory = 'vendor/jquery-1.6.4'
 
 
-class LocateCodeMirror(LocateRemote):
+class LocateCodeMirror(LocatePackage):
 
-    call('/shell/external/codemirror/')
-    url = 'https://nodeload.github.com/marijnh/CodeMirror/zipball/v2.13'
-    md5 = 'b2a4f989ba45f1778b183603f78cf883'
-    cache = 'codemirror-2.13'
-    is_zip = True
+    call('/shell/vendor/codemirror/')
+    package = __name__
+    directory = 'vendor/codemirror-2.13'
 
 

File src/htsql/tweak/shell/static/index.html

   <head>
     <base href="{{ resource_root }}">
     <title>HTSQL</title>
-    <script type="text/javascript" src="external/jquery/jquery-1.6.4.min.js"></script>
-    <link rel="stylesheet" href="external/codemirror/lib/codemirror.css">
-    <link rel="stylesheet" href="external/codemirror/theme/default.css">
+    <script type="text/javascript" src="vendor/jquery/jquery-1.6.4.min.js"></script>
+    <link rel="stylesheet" href="vendor/codemirror/lib/codemirror.css">
+    <link rel="stylesheet" href="vendor/codemirror/theme/default.css">
     <link rel="stylesheet" href="cm-htsql-mode.css">
-    <script type="text/javascript" src="external/codemirror/lib/codemirror.js"></script>
+    <script type="text/javascript" src="vendor/codemirror/lib/codemirror.js"></script>
     <script type="text/javascript" src="cm-htsql-mode.js"></script>
     <link rel="stylesheet" href="shell.css">
     <script type="text/javascript" src="shell.js"></script>