1#!/usr/bin/env python3 2 3from __future__ import print_function 4import argparse 5import os 6import json 7import zipfile 8 9from hashlib import md5 10from subprocess import check_call 11 12from get_plugin_data import get_plugin_data 13 14VERSION_TO_BRANCH = { 15 None: '2.0', 16 '1.0': '1.0', 17 '2.0': '2.0', 18} 19 20 21def build_json(dest_dir): 22 """ 23 Traverse the plugins directory to generate json data. 24 """ 25 26 plugins = {} 27 28 # All top level directories in plugin_dir are plugins 29 for dirname in next(os.walk(plugin_dir))[1]: 30 31 files = {} 32 data = {} 33 34 if dirname in [".git"]: 35 continue 36 37 dirpath = os.path.join(plugin_dir, dirname) 38 for root, dirs, filenames in os.walk(dirpath): 39 for filename in filenames: 40 ext = os.path.splitext(filename)[1] 41 42 if ext not in [".pyc"]: 43 file_path = os.path.join(root, filename) 44 with open(file_path, "rb") as md5file: 45 md5Hash = md5(md5file.read()).hexdigest() 46 files[file_path.split(os.path.join(dirpath, ''))[1]] = md5Hash 47 48 if ext in ['.py'] and not data: 49 data = get_plugin_data(os.path.join(plugin_dir, dirname, filename)) 50 51 if files and data: 52 print("Added: " + dirname) 53 data['files'] = files 54 plugins[dirname] = data 55 out_path = os.path.join(dest_dir, plugin_file) 56 with open(out_path, "w") as out_file: 57 json.dump({"plugins": plugins}, out_file, sort_keys=True, indent=2) 58 59 60def zip_files(dest_dir): 61 """ 62 Zip up plugin folders 63 """ 64 65 for dirname in next(os.walk(plugin_dir))[1]: 66 archive_path = os.path.join(dest_dir, dirname) 67 archive = zipfile.ZipFile(archive_path + ".zip", "w") 68 69 dirpath = os.path.join(plugin_dir, dirname) 70 plugin_files = [] 71 72 for root, dirs, filenames in os.walk(dirpath): 73 for filename in filenames: 74 file_path = os.path.join(root, filename) 75 plugin_files.append(file_path) 76 77 if (len(plugin_files) == 1 78 and os.path.basename(plugin_files[0]) != '__init__.py'): 79 # There's only one file, put it directly into the zipfile 80 archive.write(plugin_files[0], 81 os.path.basename(plugin_files[0]), 82 compress_type=zipfile.ZIP_DEFLATED) 83 else: 84 for filename in plugin_files: 85 # Preserve the folder structure relative to plugin_dir 86 # in the zip file 87 name_in_zip = os.path.join(os.path.relpath(filename, 88 plugin_dir)) 89 archive.write(filename, 90 name_in_zip, 91 compress_type=zipfile.ZIP_DEFLATED) 92 93 print("Created: " + dirname + ".zip") 94 95 96# The file that contains json data 97plugin_file = "plugins.json" 98 99# The directory which contains plugin files 100plugin_dir = "plugins" 101 102if __name__ == '__main__': 103 parser = argparse.ArgumentParser(description='Generate plugin files for Picard website.') 104 parser.add_argument('version', nargs='?', help="Build output files for the specified version") 105 parser.add_argument('--build_dir', default="build", help="Path for the build output. DEFAULT = %(default)s") 106 parser.add_argument('--pull', action='store_true', dest='pull', help="Pulls the remote origin and updates the files before building") 107 parser.add_argument('--no-zip', action='store_false', dest='zip', help="Do not generate the zip files in the build output") 108 parser.add_argument('--no-json', action='store_false', dest='json', help="Do not generate the json file in the build output") 109 args = parser.parse_args() 110 check_call(["git", "checkout", "-q", VERSION_TO_BRANCH[args.version], '--', 'plugins']) 111 dest_dir = os.path.abspath(os.path.join(args.build_dir, args.version or '')) 112 if not os.path.exists(dest_dir): 113 os.makedirs(dest_dir) 114 if args.pull: 115 check_call(["git", "pull", "-q"]) 116 if args.json: 117 build_json(dest_dir) 118 if args.zip: 119 zip_files(dest_dir) 120