ppub.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. from PyPPUB.asset_index import AssetIndex
  2. from PyPPUB.metadata import Metadata
  3. import gzip
  4. class Ppub:
  5. def __init__(self):
  6. self.metadata = None
  7. self.asset_index = None
  8. self.default_asset = None
  9. self.__stream = None
  10. self.__blob_start = 0
  11. self.__flag_handlers = {
  12. "gzip": lambda x: gzip.decompress(x)
  13. }
  14. @staticmethod
  15. def from_stream(stream):
  16. if (stream.read(5) != b"ppub\n"):
  17. raise Exception("Stream did not start with magic number")
  18. index_length_bytes = b""
  19. next_byte = b""
  20. while(next_byte != b"\n"):
  21. index_length_bytes += next_byte
  22. next_byte = stream.read(1)
  23. index_length = int(index_length_bytes)
  24. index_bytes = stream.read(index_length)
  25. blob_start = len(index_length_bytes) + index_length + 6
  26. index = AssetIndex.from_string(index_bytes.decode('utf-8'))
  27. obj = Ppub()
  28. obj.__stream = stream
  29. obj.__blob_start = blob_start
  30. obj.asset_index = index
  31. obj.metadata = Metadata.from_string(obj.get_asset_data(index.get_asset("metadata")).decode('utf-8'))
  32. obj.default_asset = index.get_nth_asset(1)
  33. return obj
  34. def get_asset_data(self, asset):
  35. start_location = asset.start_location + self.__blob_start
  36. length = asset.end_location - asset.start_location
  37. self.__stream.seek(start_location)
  38. data = self.__stream.read(length)
  39. for flag in asset.flags:
  40. if (flag not in self.__flag_handlers):
  41. raise Exception("Flag '%s' not understood" % flag)
  42. data = self.__flag_handlers[flag](data)
  43. return data