import json import os import shutil from tempfile import TemporaryDirectory from django.http import FileResponse from ...core.utils import slugify def export_theme(theme): with TemporaryDirectory() as tmp_dir: export_dir = create_export_directory(tmp_dir, theme) manifest = create_theme_manifest(theme) manifest["css"] = write_theme_css(export_dir, theme) manifest["media"] = write_theme_media(export_dir, theme) write_theme_manifest(export_dir, manifest) export_file = zip_theme_export(tmp_dir, export_dir) export_filename = os.path.split(export_file)[-1] response = FileResponse(open(export_file, "rb"), content_type="application/zip") response['Content-Length'] = os.path.getsize(export_file) response['Content-Disposition'] = "inline; filename=%s" % export_filename return response def create_export_directory(tmp_dir, theme): export_name = get_export_name(theme) export_dir = os.path.join(tmp_dir, export_name) os.mkdir(export_dir) return export_dir def get_export_name(theme): if theme.version: return "%s-%s" % (slugify(theme.name), theme.version.replace(".", "-")) return slugify(theme.name) def create_theme_manifest(theme): return { "name": theme.name, "version": theme.version, "author": theme.author, "url": theme.url, "css": [], "media": [], } def write_theme_css(export_dir, theme): files_dir = create_sub_directory(export_dir, "css") files = [] for css in theme.css.all(): if css.url: files.append({ "name": css.name, "url": css.url, }) else: files.append({ "name": css.name, "path": copy_asset_file(files_dir, css.source_file), }) return files def write_theme_media(export_dir, theme): files_dir = create_sub_directory(export_dir, "media") files = [] for media in theme.media.all(): files.append({ "name": media.name, "type": media.type, "path": copy_asset_file(files_dir, media.file), }) return files def create_sub_directory(export_dir, dirname): new_dir = os.path.join(export_dir, dirname) os.mkdir(new_dir) return new_dir def copy_asset_file(export_dir, asset_file): filename = os.path.split(asset_file.name)[-1] dst_path = os.path.join(export_dir, filename) with open(dst_path, "wb") as fp: for chunk in asset_file.chunks(): fp.write(chunk) dirname = os.path.basename(export_dir) return os.path.join(dirname, filename) def write_theme_manifest(export_dir, manifest): manifest_path = os.path.join(export_dir, "manifest.json") with open(manifest_path, "w") as fp: json.dump(manifest, fp, ensure_ascii=False, indent=2) def zip_theme_export(tmp_dir, export_dir): dir_name = os.path.split(export_dir)[-1] zip_name = shutil.make_archive(dir_name, 'zip', tmp_dir) return os.path.join(tmp_dir, zip_name)