Abilty to get book from just IA url

This commit is contained in:
bipinkrish 2023-02-26 19:30:51 +05:30
parent b6a000b7b9
commit d4999b9c48
4 changed files with 231 additions and 51 deletions

View file

@ -7,34 +7,43 @@ from decrypt.decodeEPUB import decryptEPUB
import argparse import argparse
from os import mkdir, remove, rename from os import mkdir, remove, rename
from os.path import exists from os.path import exists
from sys import exit
from setup.params import FILE_DEVICEKEY, FILE_DEVICEXML, FILE_ACTIVATIONXML from setup.params import FILE_DEVICEKEY, FILE_DEVICEXML, FILE_ACTIVATIONXML
from decrypt.params import KEYPATH from decrypt.params import KEYPATH
from setup.data import createDefaultFiles from setup.data import createDefaultFiles
from setup.ia import SESSION_FILE, manage_login, get_book, return_book
def main(acsmFile, login, outputFilename):
# user login def loginADE(email, password):
if login: if email is None or password is None:
if not exists("account"): print("Email or Password cannot be empty")
mkdir("account") print()
loginAndGetKey() return
exit(0) if not exists('account'): mkdir('account')
loginAndGetKey(email, password)
print()
def loginIA(email,password):
if email is None or password is None:
print("Email or Password cannot be empty")
print()
return
manage_login(email,password)
print()
def main(acsmFile, outputFilename):
if not exists('account'): mkdir('account')
# setting up the account and keys # setting up the account and keys
if not (exists(FILE_ACTIVATIONXML) and exists(FILE_DEVICEXML) and exists(FILE_DEVICEKEY) and exists(KEYPATH)): if not (exists(FILE_ACTIVATIONXML) and exists(FILE_DEVICEXML) and exists(FILE_DEVICEKEY) and exists(KEYPATH)):
if not exists("account"):
mkdir("account")
createDefaultFiles() createDefaultFiles()
print() print()
# cheek for file existance # cheek for file existance
if not exists(acsmFile): if not exists(acsmFile):
print(f"{acsmFile} file does not exist") print(f"{acsmFile} file does not exist")
print() print()
exit(1) return
# download # download
encryptedFile = downloadFile(acsmFile) encryptedFile = downloadFile(acsmFile)
@ -49,7 +58,7 @@ def main(acsmFile, login, outputFilename):
else: else:
print("File format not supported") print("File format not supported")
print() print()
exit(1) return
remove(encryptedFile) remove(encryptedFile)
if outputFilename is None: if outputFilename is None:
@ -60,20 +69,69 @@ def main(acsmFile, login, outputFilename):
print(tempName) print(tempName)
print() print()
def handle_IA(url,format):
if not exists(SESSION_FILE):
print("Login to InternetArchive first or give ACSm file as input")
return
acsmFile = get_book(url,format)
if acsmFile is None:
print("Could not get Book, try using ACSm file as input")
return
main(acsmFile,None)
remove(acsmFile)
if(return_book(url) is None):
print("Please return it yourself")
if __name__ == "__main__": if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Download and Decrypt an encrypted PDF or EPUB file. It uses Dummy account for ADE, you can overide using --login") parser = argparse.ArgumentParser(description="Download and Decrypt an encrypted PDF or EPUB file.")
parser.add_argument("file", type=str, nargs='?', default=None, help="Path to the ACSM file") parser.add_argument("-f", type=str, nargs='?', default=None, help="path to the ACSM file")
parser.add_argument("-l", "--login", action="store_true", help="Login to your ADE account. (optional)") parser.add_argument("-u", type=str, nargs='?', default=None, help="book url from InternetArchive")
parser.add_argument("-o", "--output", type=str, default=None, help="Output file name. (optional)") parser.add_argument("-t", type=str, nargs='?', default='pdf', help="book file type/format/extension for book url (defaults to PDF)")
parser.add_argument("-o", type=str, nargs='?', default=None, help="output file name")
parser.add_argument("-la", action="store_true", help="login to your ADE account.")
parser.add_argument("-li", action="store_true", help="login to your InternetArchive.")
parser.add_argument("-e", type=str, nargs='?', default=None, help="email/username")
parser.add_argument("-p", type=str, nargs='?', default=None, help="password")
parser.add_argument("-lo", action="store_true", help="logout from all")
args = parser.parse_args() args = parser.parse_args()
# check for default value # Logout
if args.file == None: if args.lo:
if exists("URLLink.acsm"): from shutil import rmtree
args.file = "URLLink.acsm" rmtree("account")
else: mkdir('account')
parser.print_help() print()
exit(0) print("Logout Sucessfull")
print()
main(args.file, args.login, args.output) # ADE login
elif args.la:
print()
print("chose login for ADE")
loginADE(args.e, args.p)
# IA login
elif args.li:
print()
print("chose login for InternetArchive")
loginIA(args.e, args.p)
# Book url
elif args.u:
print()
if not args.t in ['pdf','epub']:
print("only PDF and EPUB are supported")
else:
handle_IA(args.u, args.t)
print()
# check for default value
elif args.f == None:
if exists("URLLink.acsm"):
args.f = "URLLink.acsm"
main(args.f, args.output)
else: parser.print_help()
else:
main(args.f, args.output)

View file

@ -1,3 +1,4 @@
pycryptodomex==3.17 pycryptodomex==3.17
oscrypto==1.3.0 oscrypto==1.3.0
lxml==4.9.2 lxml==4.9.2
requests

135
setup/ia.py Normal file
View file

@ -0,0 +1,135 @@
from os import path, mkdir
import requests
import random
import string
import pickle
SESSION_FILE = 'account/session.pkl'
session = None
if path.exists(SESSION_FILE):
with open(SESSION_FILE, 'rb') as f: session = pickle.load(f)
# print error
def display_error(response, message):
print(message)
print(response)
print(response.text)
# login and format
def format_data(content_type, fields):
data = ""
for name, value in fields.items():
data += f"--{content_type}\x0d\x0aContent-Disposition: form-data; name=\"{name}\"\x0d\x0a\x0d\x0a{value}\x0d\x0a"
data += content_type+"--"
return data
def login(email, password):
session = requests.Session()
session.get("https://archive.org/account/login")
content_type = "----WebKitFormBoundary"+"".join(random.sample(string.ascii_letters + string.digits, 16))
headers = {'Content-Type': 'multipart/form-data; boundary='+content_type}
data = format_data(content_type, {"username":email, "password":password, "submit_by_js":"true"})
response = session.post("https://archive.org/account/login", data=data, headers=headers)
if "bad_login" in response.text:
print("[-] Invalid credentials!")
return None
elif "Successful login" in response.text:
print("[+] Successful login")
return session
else:
display_error(response, "[-] Error while login:")
return None
# get book
def loan(book_id):
global session
if not session:
with open(SESSION_FILE, 'rb') as f: session = pickle.load(f)
data = {
"action": "grant_access",
"identifier": book_id
}
response = session.post("https://archive.org/services/loans/loan/searchInside.php", data=data)
data['action'] = "browse_book"
response = session.post("https://archive.org/services/loans/loan/", data=data)
if response.status_code == 400 :
if response.json()["error"] == "This book is not available to borrow at this time. Please try again later.":
print("This book doesn't need to be borrowed")
return session
else :
display_error(response, "Something went wrong when trying to borrow the book.")
return None
data['action'] = "create_token"
response = session.post("https://archive.org/services/loans/loan/", data=data)
if "token" in response.text:
print("[+] Successful loan")
return session
else:
display_error(response, "Something went wrong when trying to borrow the book, maybe you can't borrow this book.")
return None
# acsm file
def get_acsmfile(bookid,format="pdf"):
global session
if not session:
with open(SESSION_FILE, 'rb') as f: session = pickle.load(f)
response = session.get(f"https://archive.org/services/loans/loan/?action=media_url&format={format}&redirect=1&identifier={bookid}")
if response.status_code == 200:
with open(f"{bookid}.acsm","w") as af: af.write(response.text)
return f"{bookid}.acsm"
else:
display_error(response, "Something went wrong when trying to get ACSM")
return None
# return the book
def return_loan(book_id):
global session
if not session:
with open(SESSION_FILE, 'rb') as f: session = pickle.load(f)
data = {
"action": "return_loan",
"identifier": book_id
}
response = session.post("https://archive.org/services/loans/loan/", data=data)
if response.status_code == 200 and response.json()["success"]:
print("[+] Book returned")
return True
else:
display_error(response, "Something went wrong when trying to return the book")
return None
# manage
def manage_login(email,password):
global session
if not path.exists('account'): mkdir('account')
sess = login(email,password)
if sess is not None:
with open(SESSION_FILE, 'wb') as f: pickle.dump(sess, f)
session = sess
def get_book(url,format):
global session
bookid = url.split("/")[4]
sess = loan(bookid)
if sess is not None:
with open(SESSION_FILE, 'wb') as f: pickle.dump(sess, f)
session = sess
return get_acsmfile(bookid,format)
return None
def return_book(url):
bookid = url.split("/")[4]
return return_loan(bookid)

View file

@ -16,21 +16,7 @@ from decrypt.params import KEYPATH
################################################################# #################################################################
def takeInput(): def loginAndGetKey(email, password):
global VAR_MAIL
global VAR_PASS
VAR_MAIL = input("Enter Mail: ")
VAR_PASS = input("Enter Password: ")
if VAR_MAIL == "" or VAR_MAIL == "":
print("It cannot be empty")
print()
exit(1)
def loginAndGetKey():
global VAR_MAIL global VAR_MAIL
global VAR_PASS global VAR_PASS
@ -40,31 +26,32 @@ def loginAndGetKey():
# acc files # acc files
if True: if True:
takeInput() VAR_MAIL = email
print("Logging in") VAR_PASS = password
print("Logging in")
createDeviceKeyFile() createDeviceKeyFile()
success = createDeviceFile(True, VAR_VER) success = createDeviceFile(True, VAR_VER)
if (success is False): if (success is False):
print("Error, couldn't create device file.") print("Error, couldn't create device file.")
exit(1) return
success, resp = createUser(VAR_VER, None) success, resp = createUser(VAR_VER, None)
if (success is False): if (success is False):
print("Error, couldn't create user: %s" % resp) print("Error, couldn't create user: %s" % resp)
exit(1) return
success, resp = signIn("AdobeID", VAR_MAIL, VAR_PASS) success, resp = signIn("AdobeID", VAR_MAIL, VAR_PASS)
if (success is False): if (success is False):
print("Login unsuccessful: " + resp) print("Login unsuccessful: " + resp)
exit(1) return
success, resp = activateDevice(VAR_VER, None) success, resp = activateDevice(VAR_VER, None)
if (success is False): if (success is False):
print("Couldn't activate device: " + resp) print("Couldn't activate device: " + resp)
exit(1) return
print("Authorized to account " + VAR_MAIL) print("Authorized to account " + VAR_MAIL)
@ -79,16 +66,15 @@ def loginAndGetKey():
success = exportAccountEncryptionKeyDER(filename) success = exportAccountEncryptionKeyDER(filename)
if (success is False): if (success is False):
print("Couldn't export key.") print("Couldn't export key.")
exit(1) return
print("Successfully exported key for account " + VAR_MAIL + " to file " + filename) print("Successfully exported key for account " + VAR_MAIL + " to file " + filename)
else: else:
print("failed") print("failed")
exit(1)
except Exception as e: except Exception as e:
print(e) print(e)
exit(1)
print('All Set') print('All Set')
print() print()