Fix ZipDocument format

This commit is contained in:
Stijn Van Campenhout
2019-11-27 13:38:53 +01:00
parent 64054a33b3
commit 3046764750

View File

@@ -1,13 +1,15 @@
import os
from io import BytesIO from io import BytesIO
from zipfile import ZipFile, ZIP_DEFLATED from zipfile import ZipFile, ZIP_DEFLATED
import shutil import shutil
from uuid import uuid4 from uuid import uuid4
import json import json
from typing import NoReturn, TypeVar, List from typing import NoReturn, TypeVar, List, Tuple
from requests import Response from requests import Response
from .meta import Meta from .meta import Meta
BytesOrString = TypeVar("BytesOrString", BytesIO, str) BytesOrString = TypeVar("BytesOrString", BytesIO, str)
BytesOrNone = TypeVar("BytesOrNone", BytesIO, None)
class RmPage(object): class RmPage(object):
@@ -110,41 +112,49 @@ class ZipDocument(object):
rm: A list of :class:rmapi.document.RmPage in this zip. rm: A list of :class:rmapi.document.RmPage in this zip.
""" """
# {"extraMetadata": {},
# "fileType": "pdf",
# "pageCount": 0,
# "lastOpenedPage": 0,
# "lineHeight": -1,
# "margins": 180,
# "textScale": 1,
# "transform": {}}
content = { content = {
"ExtraMetadata": { "extraMetadata": {
"LastBrushColor": "Black", # "LastBrushColor": "Black",
"LastBrushThicknessScale": "2", # "LastBrushThicknessScale": "2",
"LastColor": "Black", # "LastColor": "Black",
"LastEraserThicknessScale": "2", # "LastEraserThicknessScale": "2",
"LastEraserTool": "Eraser", # "LastEraserTool": "Eraser",
"LastPen": "Ballpoint", # "LastPen": "Ballpoint",
"LastPenColor": "Black", # "LastPenColor": "Black",
"LastPenThicknessScale": "2", # "LastPenThicknessScale": "2",
"LastPencil": "SharpPencil", # "LastPencil": "SharpPencil",
"LastPencilColor": "Black", # "LastPencilColor": "Black",
"LastPencilThicknessScale": "2", # "LastPencilThicknessScale": "2",
"LastTool": "SharpPencil", # "LastTool": "SharpPencil",
"ThicknessScale": "2" # "ThicknessScale": "2"
}, },
"FileType": "", # "FileType": "",
"FontName": "", # "FontName": "",
"LastOpenedPage": 0, "lastOpenedPage": 0,
"LineHeight": -1, "lineHeight": -1,
"Margins": 100, "margins": 180,
"Orientation": "portrait", # "Orientation": "portrait",
"PageCount": 0, "pageCount": 0,
"Pages": [], # "Pages": [],
"TextScale": 1, "textScale": 1,
"Transform": { "transform": {
"M11": 1, # "M11": 1,
"M12": 0, # "M12": 0,
"M13": 0, # "M13": 0,
"M21": 0, # "M21": 0,
"M22": 1, # "M22": 1,
"M23": 0, # "M23": 0,
"M31": 0, # "M31": 0,
"M32": 0, # "M32": 0,
"M33": 1, # "M33": 1,
} }
} }
@@ -158,10 +168,10 @@ class ZipDocument(object):
"synced": True, "synced": True,
"type": "DocumentType", "type": "DocumentType",
"version": 1, "version": 1,
"visibleName": "New Document" "VissibleName": "New Document"
} }
pagedata = "" pagedata = "b''"
zipfile = BytesIO() zipfile = BytesIO()
pdf = None pdf = None
@@ -183,20 +193,23 @@ class ZipDocument(object):
if doc: if doc:
ext = doc[-4:] ext = doc[-4:]
if ext.endswith("pdf"): if ext.endswith("pdf"):
self.content["FileType"] = "pdf" self.content["fileType"] = "pdf"
self.pdf = BytesIO() self.pdf = BytesIO()
with open(doc, 'rb') as fb: with open(doc, 'rb') as fb:
self.pdf.write(fb.read()) self.pdf.write(fb.read())
self.pdf.seek(0)
if ext.endswith("epub"): if ext.endswith("epub"):
self.content["FileType"] = "epub" self.content["fileType"] = "epub"
self.epub = BytesIO() self.epub = BytesIO()
with open(doc, 'rb') as fb: with open(doc, 'rb') as fb:
self.epub.write(fb.read()) self.epub.write(fb.read())
self.epub.seek(0)
elif ext.endswith("rm"): elif ext.endswith("rm"):
self.content["FileType"] = "notebook" self.content["fileType"] = "notebook"
self.pdf = BytesIO()
with open(doc, 'rb') as fb: with open(doc, 'rb') as fb:
self.rm.append(RmPage(page=BytesIO(doc.read()))) self.rm.append(RmPage(page=BytesIO(doc.read())))
name = os.path.splitext(os.path.basename(doc))[0]
self.metadata["VissibleName"] = name
if file: if file:
self.load(file) self.load(file)
@@ -209,7 +222,14 @@ class ZipDocument(object):
"""string representation of this class""" """string representation of this class"""
return self.__str__() return self.__str__()
def dump(self, file: str) -> None: def create_request(self) -> Tuple[BytesIO, dict]:
return self.zipfile, {
"ID": self.ID,
"Type": "DocumentType",
"Version": self.metadata["version"]
}
def dump(self, file: BytesOrString) -> None:
"""Dump the contents of ZipDocument back to a zip file. """Dump the contents of ZipDocument back to a zip file.
This builds a zipfile to upload back to the Remarkable Cloud. This builds a zipfile to upload back to the Remarkable Cloud.
@@ -218,14 +238,11 @@ class ZipDocument(object):
file: Where to save the zipfile file: Where to save the zipfile
""" """
with ZipFile(file, "w", ZIP_DEFLATED) as zf:
with ZipFile(f"{file}.zip", "w", ZIP_DEFLATED) as zf: zf.writestr(f"{self.ID}.content",
if self.content: json.dumps(self.content))
zf.writestr(f"{self.ID}.content", zf.writestr(f"{self.ID}.pagedata",
json.dumps(self.content)) self.pagedata)
if self.pagedata:
zf.writestr(f"{self.ID}.pagedata",
self.pagedata)
if self.pdf: if self.pdf:
zf.writestr(f"{self.ID}.pdf", zf.writestr(f"{self.ID}.pdf",
@@ -245,6 +262,8 @@ class ZipDocument(object):
page.page.seek(0) page.page.seek(0)
zf.writestr(f"{self.ID}.thumbnails/{page.order}.jpg", zf.writestr(f"{self.ID}.thumbnails/{page.order}.jpg",
page.thumbnail.read()) page.thumbnail.read())
if isinstance(file, BytesIO):
file.seek(0)
def load(self, file: BytesOrString) -> None: def load(self, file: BytesOrString) -> None:
"""Load a zipfile into this class. """Load a zipfile into this class.
@@ -281,13 +300,13 @@ class ZipDocument(object):
pass pass
try: try:
with zf.open(f"{self.ID}.pdf", 'rb') as pdf: with zf.open(f"{self.ID}.pdf", 'r') as pdf:
self.pdf = BytesIO(pdf.read()) self.pdf = BytesIO(pdf.read())
except KeyError: except KeyError:
pass pass
try: try:
with zf.open(f"{self.ID}.epub", 'rb') as epub: with zf.open(f"{self.ID}.epub", 'r') as epub:
self.epub = BytesIO(epub.read()) self.epub = BytesIO(epub.read())
except KeyError: except KeyError:
pass pass