import json
import logging
import os
import re
import zipfile
from distutils.version import StrictVersion

import requests

base_dir = os.path.dirname(os.path.abspath(__file__))
repo_dir = os.path.join(base_dir, "site", "dat", "repo")
dest_dir = os.path.join(base_dir, "site", "files", "packages")


def is_version_packed(fname):
    resp = requests.head("https://jmeter-plugins.org/files/packages/%s" % fname)
    resp.close()
    return resp.status_code == 200


def pack_version(fname, ver_obj, pmgr_obj):
    if not ver_obj['downloadUrl']:
        return

    with zipfile.ZipFile(fname, 'w', zipfile.ZIP_DEFLATED) as ziph:
        # pack main file
        download_into_zip(ziph, ver_obj['downloadUrl'], os.path.join("lib", "ext"))

        # pack libs
        if 'libs' in ver_obj:
            for libname in ver_obj['libs']:
                download_into_zip(ziph, ver_obj['libs'][libname], os.path.join("lib"))

        # pack pmgr
        download_into_zip(ziph, pmgr_obj['downloadUrl'], os.path.join("lib", "ext"))


def download_into_zip(ziph, url, dest_subpath):
    """
    :type ziph: zipfile.ZipFile
    :type url: str
    """
    logging.info("Downloading: %s", url)
    resp = requests.get(url)
    assert resp.status_code == 200
    if 'content-disposition' in resp.headers:
        remote_filename = re.findall("filename=(.+)", resp.headers['content-disposition'])[0]
    else:
        remote_filename = os.path.basename(resp.url)
    ziph.writestr(os.path.join(dest_subpath, remote_filename), resp.content)
    resp.close()


def get_pmgr(plugins_list):
    for plug in plugins_list:
        if plug['id'] == 'jpgc-plugins-manager':
            versions = sorted(plug['versions'].keys(), key=StrictVersion)
            return plug['versions'][versions[-1]]

    raise Exception("Failed to find plugins manager meta info")


if __name__ == "__main__":
    logging.basicConfig(level=logging.DEBUG)

    if not os.path.exists(dest_dir):
        os.makedirs(dest_dir)

    plugins = []
    for repo_file in os.listdir(repo_dir):
        with open(os.path.join(repo_dir, repo_file)) as fhd:
            plugins.extend(json.loads(fhd.read()))

    # find pmgr
    pmgr_obj = get_pmgr(plugins)

    for plugin in plugins:
        logging.debug("Processing plugin: %s", plugin['id'])
        if plugin['id'] == 'jpgc-plugins-manager':
            continue

        for version in plugin['versions']:
            logging.debug("Version: %s", version)
            if not version:
                continue
            dest_file = "%s-%s.zip" % (plugin['id'], version)
            if is_version_packed(dest_file):
                logging.info("Skip: %s", plugin['id'])
                continue

            pack_version(os.path.join(dest_dir, dest_file), plugin['versions'][version], pmgr_obj)

@@ -40,16 +40,50 @@
 port re%0A
+import subprocess%0Aimport tempfile%0A
 import z
@@ -89,16 +89,17 @@
 zipfile%0A
+%0A
 from dis
@@ -134,17 +134,16 @@
 Version%0A
-%0A
 import r
@@ -533,16 +533,31 @@
 pmgr_obj
+, installer_cls
 ):%0A    i
@@ -682,32 +682,73 @@
     
-# pack
+tmp_dir = tempfile.mkdtemp()%0A%0A        # download
  main 
-file
+jar
 %0A       
  dow
@@ -735,32 +735,43 @@
 main jar%0A       
+ jar_path =
  download_into_z
@@ -765,32 +765,35 @@
 wnload_into_
-zip(ziph
+dir(tmp_dir
 , ver_obj%5B'd
@@ -843,22 +843,192 @@
         
-# pack
+if installer_cls is not None:%0A            os.mkdir(os.path.join(tmp_dir, 'bin'))%0A            subprocess.check_call(%5B%22java%22, %22-cp%22, jar_path, installer_cls%5D)%0A%0A        # download
  libs%0A  
@@ -1129,24 +1129,27 @@
 ad_into_
-zip(ziph
+dir(tmp_dir
 , ver_ob
@@ -1200,20 +1200,24 @@
       # 
-pack
+download
  pmgr%0A  
@@ -1236,24 +1236,27 @@
 ad_into_
-zip(ziph
+dir(tmp_dir
 , pmgr_o
@@ -1307,123 +1307,331 @@
 ))%0A%0A
-%0Adef download_into_zip(ziph, url, dest_subpath):%0A    %22%22%22%0A    :type ziph: zipfile.ZipFile%0A    :type url: str%0A    %22%22%22
+        # archive temp folder%0A        zip_dir(tmp_dir, ziph)%0A%0A%0Adef zip_dir(path, ziph):%0A    # ziph is zipfile handle%0A    for root, dirs, files in os.walk(path):%0A        for file in files:%0A            ziph.write(os.path.join(root, file), os.path.join(root%5Blen(path):%5D, file))%0A%0A%0Adef download_into_dir(dir, url, dest_subpath):
 %0A   
@@ -1939,25 +1939,139 @@
 rl)%0A
+%0A
     
-ziph.writestr
+dir_path = os.path.join(dir, dest_subpath)%0A    if not os.path.exists(dir_path):%0A        os.makedirs(dir_path)%0A%0A    file = open
 (os.
@@ -2076,24 +2076,29 @@
 s.path.join(
+dir, 
 dest_subpath
@@ -2121,37 +2121,125 @@
 e), 
-resp.content)%0A    resp.close(
+'w')%0A    file.write(resp.content)%0A    file.close()%0A    resp.close()%0A    return os.path.join(dir_path, remote_filename
 )%0A%0A%0A
@@ -3492,10 +3492,40 @@
 pmgr_obj
+, plugin.get('installerClass')
 )%0A

Make installable files for plugins available in ZIPs (#129)