acsm-calibre-plugin/calibre-plugin/fulfill.py

145 lines
4.3 KiB
Python
Raw Normal View History

2021-09-25 20:24:03 +06:00
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''
2023-02-24 19:11:15 +06:00
Copyright (c) 2021-2023 Leseratte10
This file is part of the ACSM Input Plugin by Leseratte10
ACSM Input Plugin for Calibre / acsm-calibre-plugin
For more information, see:
https://github.com/Leseratte10/acsm-calibre-plugin
2021-09-25 20:24:03 +06:00
'''
# pyright: reportUndefinedVariable=false
import sys, os, time, shutil
2021-09-25 20:24:03 +06:00
import zipfile
from lxml import etree
from libadobe import sendHTTPRequest_DL2FILE
2021-09-25 20:24:03 +06:00
from libadobeFulfill import buildRights, fulfill
from libpdf import patch_drm_into_pdf
2021-09-25 20:24:03 +06:00
FILE_DEVICEKEY = "devicesalt"
FILE_DEVICEXML = "device.xml"
FILE_ACTIVATIONXML = "activation.xml"
#######################################################################
def download(replyData):
# replyData: str
2021-09-25 20:24:03 +06:00
adobe_fulfill_response = etree.fromstring(replyData)
NSMAP = { "adept" : "http://ns.adobe.com/adept" }
adNS = lambda tag: '{%s}%s' % ('http://ns.adobe.com/adept', tag)
adDC = lambda tag: '{%s}%s' % ('http://purl.org/dc/elements/1.1/', tag)
print (replyData)
2021-09-25 20:24:03 +06:00
download_url = adobe_fulfill_response.find("./%s/%s/%s" % (adNS("fulfillmentResult"), adNS("resourceItemInfo"), adNS("src"))).text
resource_id = adobe_fulfill_response.find("./%s/%s/%s" % (adNS("fulfillmentResult"), adNS("resourceItemInfo"), adNS("resource"))).text
license_token_node = adobe_fulfill_response.find("./%s/%s/%s" % (adNS("fulfillmentResult"), adNS("resourceItemInfo"), adNS("licenseToken")))
rights_xml_str = buildRights(license_token_node)
if (rights_xml_str is None):
print("Building rights.xml failed!")
2022-04-28 20:50:55 +06:00
return False
2021-09-25 20:24:03 +06:00
book_name = None
2021-09-25 20:24:03 +06:00
try:
2021-12-15 15:09:52 +06:00
metadata_node = adobe_fulfill_response.find("./%s/%s/%s" % (adNS("fulfillmentResult"), adNS("resourceItemInfo"), adNS("metadata")))
2021-09-25 20:24:03 +06:00
book_name = metadata_node.find("./%s" % (adDC("title"))).text
except:
book_name = "Book"
2021-09-25 20:24:03 +06:00
# Download eBook:
print(download_url)
filename_tmp = book_name + ".tmp"
dl_start_time = int(time.time() * 1000)
ret = sendHTTPRequest_DL2FILE(download_url, filename_tmp)
dl_end_time = int(time.time() * 1000)
print("Download took %d milliseconds" % (dl_end_time - dl_start_time))
if (ret != 200):
print("Download failed with error %d" % (ret))
2022-04-28 20:50:55 +06:00
return False
with open(filename_tmp, "rb") as f:
book_content = f.read(10)
2021-09-25 20:24:03 +06:00
filetype = ".bin"
if (book_content.startswith(b"PK")):
print("That's a ZIP file -> EPUB")
filetype = ".epub"
elif (book_content.startswith(b"%PDF")):
print("That's a PDF file")
filetype = ".pdf"
filename = book_name + filetype
shutil.move(filename_tmp, filename)
2021-09-25 20:24:03 +06:00
if filetype == ".epub":
# Store EPUB rights / encryption stuff
zf = zipfile.ZipFile(filename, "a")
zf.writestr("META-INF/rights.xml", rights_xml_str)
zf.close()
print("File successfully fulfilled to " + filename)
2022-04-28 20:50:55 +06:00
return True
2021-09-25 20:24:03 +06:00
elif filetype == ".pdf":
print("Successfully downloaded PDF, patching encryption ...")
adobe_fulfill_response = etree.fromstring(rights_xml_str)
NSMAP = { "adept" : "http://ns.adobe.com/adept" }
adNS = lambda tag: '{%s}%s' % ('http://ns.adobe.com/adept', tag)
resource = adobe_fulfill_response.find("./%s/%s" % (adNS("licenseToken"), adNS("resource"))).text
os.rename(filename, "tmp_" + filename)
ret = patch_drm_into_pdf("tmp_" + filename, rights_xml_str, filename, resource)
os.remove("tmp_" + filename)
if (ret):
print("File successfully fulfilled to " + filename)
2022-04-28 20:50:55 +06:00
return True
else:
print("Errors occurred while patching " + filename)
2022-04-28 20:50:55 +06:00
return False
2021-09-25 20:24:03 +06:00
else:
print("Error: Weird filetype")
2022-04-28 20:50:55 +06:00
return False
2021-09-25 20:24:03 +06:00
def main():
2022-04-28 20:50:55 +06:00
if len(sys.argv) < 2:
files = [ "URLLink.acsm" ]
2021-09-25 20:24:03 +06:00
else:
2022-04-28 20:50:55 +06:00
files = sys.argv[1:]
for file in files:
print("Fulfilling book '" + file + "' ...")
success, replyData = fulfill(file)
if (success is False):
print("Hey, that didn't work!")
print(replyData)
else:
print("Downloading book '" + file + "' ...")
success = download(replyData)
if (success is False):
print("That didn't work!")
2021-09-25 20:24:03 +06:00
if __name__ == "__main__":
main()