2021-09-25 20:24:03 +06:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
'''
|
|
|
|
This is an experimental Python version of libgourou.
|
|
|
|
'''
|
|
|
|
|
|
|
|
# pyright: reportUndefinedVariable=false
|
|
|
|
|
2021-10-03 14:30:45 +06:00
|
|
|
import sys, os, time, shutil
|
2021-09-27 21:06:05 +06:00
|
|
|
if sys.version_info[0] < 3:
|
|
|
|
print("This script requires Python 3.")
|
|
|
|
exit(1)
|
|
|
|
|
2021-09-25 20:24:03 +06:00
|
|
|
import zipfile
|
|
|
|
from lxml import etree
|
|
|
|
|
2021-10-03 14:30:45 +06:00
|
|
|
from libadobe import sendHTTPRequest_DL2FILE
|
2021-09-25 20:24:03 +06:00
|
|
|
from libadobeFulfill import buildRights, fulfill
|
2021-10-03 14:30:45 +06:00
|
|
|
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"
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
|
|
|
|
2021-09-27 21:06:05 +06:00
|
|
|
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)
|
|
|
|
|
2021-09-28 22:43:14 +06:00
|
|
|
print (replyData)
|
|
|
|
|
2021-09-25 20:24:03 +06:00
|
|
|
|
|
|
|
metadata_node = adobe_fulfill_response.find("./%s/%s/%s" % (adNS("fulfillmentResult"), adNS("resourceItemInfo"), adNS("metadata")))
|
|
|
|
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!")
|
|
|
|
exit(1)
|
|
|
|
|
|
|
|
book_name = None
|
2021-10-03 14:30:45 +06:00
|
|
|
|
2021-09-25 20:24:03 +06:00
|
|
|
try:
|
|
|
|
book_name = metadata_node.find("./%s" % (adDC("title"))).text
|
|
|
|
except:
|
|
|
|
book_name = "Book"
|
2021-09-28 22:43:14 +06:00
|
|
|
|
2021-09-25 20:24:03 +06:00
|
|
|
|
|
|
|
# Download eBook:
|
|
|
|
|
2021-09-28 22:43:14 +06:00
|
|
|
print(download_url)
|
|
|
|
|
2021-10-03 14:30:45 +06:00
|
|
|
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))
|
|
|
|
exit()
|
|
|
|
|
|
|
|
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
|
2021-10-03 14:30:45 +06:00
|
|
|
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()
|
|
|
|
|
2021-09-28 22:43:14 +06:00
|
|
|
print("File successfully fulfilled to " + filename)
|
2021-09-25 20:24:03 +06:00
|
|
|
exit(0)
|
2021-09-28 22:43:14 +06:00
|
|
|
|
2021-09-25 20:24:03 +06:00
|
|
|
elif filetype == ".pdf":
|
2021-09-28 22:43:14 +06:00
|
|
|
print("Successfully downloaded PDF, patching encryption ...")
|
2021-10-03 14:30:45 +06:00
|
|
|
|
|
|
|
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
|
2021-09-28 22:43:14 +06:00
|
|
|
|
|
|
|
os.rename(filename, "tmp_" + filename)
|
2021-10-03 14:30:45 +06:00
|
|
|
ret = patch_drm_into_pdf("tmp_" + filename, rights_xml_str, filename, resource)
|
2021-09-28 22:43:14 +06:00
|
|
|
os.remove("tmp_" + filename)
|
2021-10-03 14:30:45 +06:00
|
|
|
if (ret):
|
|
|
|
print("File successfully fulfilled to " + filename)
|
|
|
|
else:
|
|
|
|
print("Errors occurred while patching " + filename)
|
|
|
|
exit(1)
|
2021-09-28 22:43:14 +06:00
|
|
|
exit(0)
|
2021-09-25 20:24:03 +06:00
|
|
|
else:
|
|
|
|
print("Error: Weird filetype")
|
|
|
|
exit(1)
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
print("Fulfilling book ...")
|
|
|
|
success, replyData = fulfill("URLLink.acsm")
|
|
|
|
if (success is False):
|
|
|
|
print("Hey, that didn't work!")
|
|
|
|
print(replyData)
|
|
|
|
else:
|
|
|
|
print("Downloading book ...")
|
|
|
|
download(replyData)
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|