knock/knock
2021-07-30 18:55:29 -05:00

89 lines
No EOL
3.2 KiB
Python

#!/usr/bin/env python3
import os, sys, argparse, subprocess, magic, shutil
from pathlib import Path
from getpass import getpass
parser = argparse.ArgumentParser(prog='knock', description='Convert an ACSM file to a DRM-free EPUB file')
parser.add_argument('acsm_file', metavar='file', type=str, help='the ACSM file to convert')
args = parser.parse_args()
# these are all Path objects: https://docs.python.org/3/library/pathlib.html
args.acsm_file = Path(args.acsm_file).expanduser().resolve()
args.drm_file = args.acsm_file.with_suffix('.drm')
args.epub_file = args.acsm_file.with_suffix('.epub')
args.adobe_dir = Path('~/.config/knock').expanduser()
if not args.acsm_file.exists():
sys.exit(f'ERROR: {str(args.acsm_file)} does not exist.')
if args.epub_file.exists():
sys.exit(f'ERROR: {str(args.epub_file)} already exists.')
if args.drm_file.exists():
sys.exit(f'ERROR: {str(args.drm_file)} must be moved or deleted.')
if not args.adobe_dir.exists():
print('This device is not registered with Adobe.')
email = input("Enter your Adobe account's email address: ")
password = getpass("Enter your Adobe account's password: ")
print('Registering this device with Adobe...')
result = subprocess.run([
'adept-register',
'-u', email,
'-O', str(args.adobe_dir)
], input=password.encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if result.stdout.decode().strip().startswith('Exception code : 0x1003'):
shutil.rmtree(str(args.adobe_dir))
sys.exit('ERROR: Incorrect password')
if result.stdout.decode().strip().startswith('Exception code : 0x500a'):
shutil.rmtree(str(args.adobe_dir))
sys.exit('ERROR: No internet access')
if result.returncode != 0 or not args.adobe_dir.exists() or result.stdout.decode().strip().startswith('Exception code : '):
if args.adobe_dir.exists():
shutil.rmtree(str(args.adobe_dir))
print('ERROR: ', file=sys.stderr)
sys.exit(result)
print('Downloading the EPUB file from Adobe...')
result = subprocess.run([
'adept-download',
'-d', str(args.adobe_dir.joinpath('device.xml')),
'-a', str(args.adobe_dir.joinpath('activation.xml')),
'-k', str(args.adobe_dir.joinpath('devicesalt')),
'-o', str(args.drm_file),
'-f', str(args.acsm_file)
], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if result.stdout.decode().strip().startswith('Exception code : 0x500a'):
sys.exit('ERROR: No internet access')
if result.returncode != 0 or not args.drm_file.exists():
print('ERROR: ', file=sys.stderr)
sys.exit(result)
drm_file_type = magic.from_file(str(args.drm_file), mime=True)
if drm_file_type != 'application/epub+zip':
sys.exit(f'Received a file of type:\n{drm_file_type}\nKnock only supports EPUB files.')
print('Decrypting the file...')
result = subprocess.run([
'inept-epub',
str(args.adobe_dir.joinpath('activation.xml')),
str(args.drm_file),
str(args.epub_file)
], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if result.returncode != 0 or not args.epub_file.exists():
print('ERROR: ', file=sys.stderr)
sys.exit(result)
args.drm_file.unlink()
print(f'\nDRM-free EPUB file created:\n{str(args.epub_file)}')