Coverage for lib/lottie/exporters/dot_lottie.py: 0%
53 statements
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-20 16:17 +0100
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-20 16:17 +0100
1import json
2import string
3import zipfile
5from .base import exporter
6from ..parsers.baseporter import ExtraOption
7from ..parsers.tgs import parse_tgs
8from lottie import __version__
9from ..objects import assets
12@exporter("dotLottie Archive", ["lottie"], [
13 ExtraOption("id", help="ID of the animation", default=None),
14 ExtraOption("append", help="Append animation to existing archive", action="store_true"),
15 ExtraOption("revision", help="File revision", type=int, default=None),
16 ExtraOption("author", help="File author", default=None),
17 ExtraOption("speed", help="Playback speed", type=float, default=1),
18 ExtraOption("theme_color", help="Theme color", type=str, default="#ffffff"),
19 ExtraOption("no_loop", help="Disable Looping", action="store_false", dest="loop"),
20 ExtraOption("no_pack", help="Don't auto-pack images", action="store_false", dest="pack_images"),
21], slug="dotlottie")
22def export_dotlottie(animation, file, id=None, append=False, revision=None, author=None,
23 speed=1.0, theme_color="#ffffff", loop=True, pack_images=True):
25 files = {}
27 if append:
28 with zipfile.ZipFile(file, "r") as zf:
29 with zf.open("manifest.json") as manifest:
30 meta = json.load(manifest)
32 for name in zf.namelist():
33 if name != "manifest.json":
34 files[name] = zf.read(name)
35 else:
36 meta = {
37 "generator": "Python Lottie " + __version__,
38 "version": 1.0,
39 "revision": 1,
40 "author": "",
41 "animations": [],
42 "custom": {}
43 }
45 if revision is not None:
46 meta["revision"] = revision
48 if author is not None:
49 meta["author"] = author
51 if id is None:
52 if animation.name:
53 idok = string.ascii_letters + string.digits + "_-"
54 id = "".join(filter(lambda x: x in idok, animation.name.replace(" ", "_")))
55 if not id:
56 id = "animation_%s" % len(meta["animations"])
58 meta["animations"].append({
59 "id": id,
60 "speed": speed,
61 "themeColor": theme_color,
62 "loop": loop,
63 })
65 if pack_images and animation.assets:
66 animation = animation.clone()
67 image_no = 0
68 for asset in animation.assets:
69 if isinstance(asset, assets.FileAsset):
70 ext, data = asset.data()
71 if not ext:
72 continue
73 pathname = "images/"
74 while True:
75 basename = "image_%s.%s" % (image_no, ext)
76 image_no += 1
77 if pathname+basename not in files:
78 break
79 files[pathname+basename] = data
80 asset.path = pathname
81 asset.file_name = basename
82 asset.is_embedded = False
84 files["manifest.json"] = json.dumps(meta)
85 files["animations/%s.json" % id] = json.dumps(animation.to_dict())
87 with zipfile.ZipFile(file, "w") as zf:
88 for name, data in files.items():
89 zf.writestr(name, data)