exporter.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import json
  2. import os
  3. import shutil
  4. from tempfile import TemporaryDirectory
  5. from django.http import FileResponse
  6. from ...core.utils import slugify
  7. def export_theme(theme):
  8. with TemporaryDirectory() as tmp_dir:
  9. export_dir = create_export_directory(tmp_dir, theme)
  10. manifest = create_theme_manifest(theme)
  11. manifest["css"] = write_theme_css(export_dir, theme)
  12. manifest["media"] = write_theme_media(export_dir, theme)
  13. write_theme_manifest(export_dir, manifest)
  14. export_file = zip_theme_export(tmp_dir, export_dir)
  15. export_filename = os.path.split(export_file)[-1]
  16. response = FileResponse(open(export_file, "rb"), content_type="application/zip")
  17. response["Content-Length"] = os.path.getsize(export_file)
  18. response["Content-Disposition"] = "inline; filename=%s" % export_filename
  19. return response
  20. def create_export_directory(tmp_dir, theme):
  21. export_name = get_export_name(theme)
  22. export_dir = os.path.join(tmp_dir, export_name)
  23. os.mkdir(export_dir)
  24. return export_dir
  25. def get_export_name(theme):
  26. if theme.version:
  27. return "%s-%s" % (slugify(theme.name), theme.version.replace(".", "-"))
  28. return slugify(theme.name)
  29. def create_theme_manifest(theme):
  30. return {
  31. "name": theme.name,
  32. "version": theme.version,
  33. "author": theme.author,
  34. "url": theme.url,
  35. "css": [],
  36. "media": [],
  37. }
  38. def write_theme_css(export_dir, theme):
  39. files_dir = create_sub_directory(export_dir, "css")
  40. files = []
  41. for css in theme.css.all():
  42. if css.url:
  43. files.append({"name": css.name, "url": css.url})
  44. else:
  45. files.append(
  46. {"name": css.name, "path": copy_asset_file(files_dir, css.source_file)}
  47. )
  48. return files
  49. def write_theme_media(export_dir, theme):
  50. files_dir = create_sub_directory(export_dir, "media")
  51. files = []
  52. for media in theme.media.all():
  53. files.append(
  54. {
  55. "name": media.name,
  56. "type": media.type,
  57. "path": copy_asset_file(files_dir, media.file),
  58. }
  59. )
  60. return files
  61. def create_sub_directory(export_dir, dirname):
  62. new_dir = os.path.join(export_dir, dirname)
  63. os.mkdir(new_dir)
  64. return new_dir
  65. def copy_asset_file(export_dir, asset_file):
  66. filename = os.path.split(asset_file.name)[-1]
  67. dst_path = os.path.join(export_dir, filename)
  68. with open(dst_path, "wb") as fp:
  69. for chunk in asset_file.chunks():
  70. fp.write(chunk)
  71. return filename
  72. def write_theme_manifest(export_dir, manifest):
  73. manifest_path = os.path.join(export_dir, "manifest.json")
  74. with open(manifest_path, "w") as fp:
  75. json.dump(manifest, fp, ensure_ascii=False, indent=2)
  76. def zip_theme_export(tmp_dir, export_dir):
  77. dir_name = os.path.split(export_dir)[-1]
  78. zip_name = shutil.make_archive(dir_name, "zip", tmp_dir)
  79. return os.path.join(tmp_dir, zip_name)