Skip to content

Instantly share code, notes, and snippets.

@JJTech0130
Last active June 12, 2021 01:58
Show Gist options
  • Save JJTech0130/f4c41c6a12ae1ec5e168a94a8c87dac1 to your computer and use it in GitHub Desktop.
Save JJTech0130/f4c41c6a12ae1ec5e168a94a8c87dac1 to your computer and use it in GitHub Desktop.
import argparse, requests, urllib, os
from pyquery import PyQuery as pq
# CLI arguments
parser = argparse.ArgumentParser(description='OverDrive helper script')
parser.add_argument('--session',
help='manually set the session id (overrides \'OD_SESSION\' env)')
parser.add_argument('book',
help='URL of the book you want to get')
parser.add_argument('--noreturn', action='store_true',
help='don\'t return the book when we\'re done')
# Error code defs
def parseError(error):
if error == 220:
return 'not enough copies available'
elif error == 640:
return 'reached checkout limit'
elif error == 710:
return 'excessive checkout limit reached'
elif error == 780:
return 'not available in correct format'
else:
return error
# Internal function for CLI
def _handleError(url):
try:
error = int(dict(urllib.parse.parse_qs(urllib.parse.urlsplit(url).query))['ErrorType'][0])
except KeyError:
return url # for the sendToAmazon function
parser.error(parseError(error))
# Checks out book
def checkoutBook(library, book, session):
return requests.get(library + 'BANGPurchase.dll?Action=OneClickCheckout&ReserveID=' + book, cookies={'SecureSession': session})
# Internal function for getting the next transaction ID
def _getTransID(library, session):
html = pq(requests.get(library + 'MyAccount.htm?PerPage=1', cookies={'SecureSession': session}).content)
return html('.myaccount-early-return').attr('data-transaction')
# Returns a book
def returnBook(library, book, session):
return requests.get(library+'BANGPurchase.dll?Action=EarlyReturn&URL=MyAccount.htm&TransactionID='+_getTransID(library, session)+'&ReserveID='+book, cookies={'SecureSession': session})
# Sends the book to Amazon
def sendToAmazon(library, book, session):
return requests.get(library + 'BANGPurchase.dll?Action=Download&FormatID=420&ReserveID=' + book, cookies={'SecureSession': session}, allow_redirects=False)
# CLI main function
if __name__ == '__main__':
args = parser.parse_args()
# Gets session ID
# TODO: Check session id validity
if args.session:
session = args.session
elif os.getenv('OD_SESSION'):
session = os.getenv('OD_SESSION')
else:
parser.error('no session specified')
# Gets the book ID and library base from the book url
try:
book = dict(urllib.parse.parse_qs(urllib.parse.urlsplit(args.book).query))['id'][0]
liburl = urllib.parse.urljoin(args.book, '/10/45/en/')
except:
parser.error("invalid book URL")
_handleError(checkoutBook(liburl, book, session).url)
print(_handleError(sendToAmazon(liburl, book, session).headers['Location']))
if not args.noreturn:
_handleError(returnBook(liburl, book, session).url)
@JJTech0130
Copy link
Author

You can also import it as a library and use it in another program.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment