Abilty to get book from just IA url
This commit is contained in:
parent
b6a000b7b9
commit
d4999b9c48
4 changed files with 231 additions and 51 deletions
108
DeGourou.py
108
DeGourou.py
|
@ -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)
|
||||||
|
|
|
@ -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
135
setup/ia.py
Normal 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)
|
|
@ -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()
|
Loading…
Reference in a new issue