Advertisement
Conquistadork

rakuten python

Nov 10th, 2018
254
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.65 KB | None | 0 0
  1. import re
  2. import requests
  3. import xml.etree.ElementTree as ET
  4. import string
  5. import io
  6. import base64
  7. import zipfile
  8. import binascii
  9. from Crypto.Cipher import AES
  10. import hashlib
  11. import StringIO
  12. import sys
  13. import os
  14. import time
  15. import uuid
  16. import random
  17. timestr = time.strftime("%Y%m%d-%H%M%S")
  18.  
  19.  
  20. path = "U:\Rakuten Downloads"
  21.  
  22. os.chdir(path)
  23.  
  24. EMAIL = sys.argv[1]
  25. print EMAIL
  26. PASSWORD = sys.argv[2]
  27. DOMAIN = 'rakuten'
  28.  
  29. def SHA256(raw):
  30.     return hashlib.sha256(raw).hexdigest()
  31.  
  32. def RemoveAESPadding(contents):
  33.     lastchar = binascii.b2a_hex(contents[-1:])
  34.     strlen = int(lastchar, 16)
  35.     padding = strlen
  36.     if(strlen == 1):
  37.         return contents[:-1]
  38.     if(strlen < 16):
  39.         for i in range(strlen):
  40.             testchar = binascii.b2a_hex(contents[-strlen:-(strlen-1)])
  41.             if(testchar != lastchar):
  42.                 padding = 0
  43.     if(padding > 0):
  44.         contents = contents[:-padding]
  45.     return contents
  46.  
  47. def LoadUserAgents(uafile="C:\Python27\user_agents.txt"):
  48.     uas = []
  49.     with open(uafile, 'rb') as uaf:
  50.         for ua in uaf.readlines():
  51.             if ua:
  52.                 uas.append(ua.strip()[1:-1-1])
  53.     random.shuffle(uas)
  54.     return uas
  55. #load user agent, set headers
  56. uas = LoadUserAgents()
  57. ua = random.choice(uas) #select random user agent
  58. baseheaders = {'MobileAPIVersion':'4.0',
  59.                'User-Agent':'ua' + 'KoboApp/6.2.13395 KoboPlatform Id/00000000-0000-0000-0000-000000004000 KoboAffiliate/Kobo',}
  60.  
  61. a = requests.Session()
  62. #This is where the server limit kicks in, I think. AttributeError Traceback, have to wait a bit
  63. request = a.post('https://secure.kobobooks.com/90034/auth/%s/Authenticate' % DOMAIN,
  64.                  params={'wscfv':'1.5','wscf':'kepub','wsa':'Kobo',
  65.                          'pwspid':'00000000-0000-0000-0000-000000004000','pwsdid':'3',
  66.                          'pwspt':'Mobile','pwspov':'16','pwsav':'6.2.13395'},
  67.                  data={'RequireSharedToken':'False','AffiliateObject.Name':'Kobo',
  68.                        'EditModel.AuthenticationAction':'Authenticate','IsFTE':'False',
  69.                        'EditModel.Email':EMAIL,'EditModel.Password':PASSWORD})
  70.  
  71. matcher = re.search('userId=(.*?)&userKey=(.*?)&', request.text)
  72. if matcher is not None:
  73.     userid = matcher.group(1)
  74.     userkey = matcher.group(2)
  75. else:
  76.     matcher = re.search('<input id="InterstitialModel_SUID" name="InterstitialModel.SUID" type="hidden" value="(.*?)"', request.text)
  77.     SUID = matcher.group(1)
  78.     matcher = re.search('<input id="InterstitialModel_SUK" name="InterstitialModel.SUK" type="hidden" value="(.*?)"', request.text)
  79.     SUK = matcher.group(1)
  80.     request = a.post('https://secure.kobobooks.com/90034/auth/%s/AcceptInterstitial' % DOMAIN,
  81.                  params={'wscfv':'2.0','wscf':'kepub','wsa':'kobodesktop','pwspid':'00000000-0000-0000-0000-000000000010','pwsdid':'3','pwspt':'Desktop','pwspov':'6.1.7601','pwsav':'3.15.0'},
  82.                  data={'RequireSharedToken':'False','AffiliateObject.Name':'Kobo','EditModel.AuthenticationAction':'Interstitial','IsFTE':'False',
  83.                        'InterstitialModel.SUID':SUID,'InterstitialModel.SUK':SUK,'InterstitialModel.IsNewUser':'False',
  84.                        'EditModel.PartnerEmailCheckbox.Checked':'false','EditModel.TermsOfUseCheckbox.Checked':'true'})
  85.  
  86.     matcher = re.search('userId=(.*?)&userKey=(.*?)&', request.text)
  87.     userid = matcher.group(1)
  88.     userkey = matcher.group(2)
  89.  
  90. print userid
  91. #print userkey
  92.  
  93. subheaders = {"Host": "mobile.kobobooks.com",'Content-Type':'text/xml','MobileRequestType':'TabRequest'}
  94. subheaders.update(baseheaders)
  95. request = a.post('http://mobile.kobobooks.com/90034/mobileRequest.ashx', """
  96. <?xml version="1.0" encoding="UTF-8"?>
  97. <TabRequest xmlns="http://kobobooks.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://kobobooks.com Requests.xsd">
  98.   <RequestHeader>
  99.      <UserID>%s</UserID>
  100.      <UserKey>%s</UserKey>
  101.   </RequestHeader>
  102.   <RequestBody>
  103.      <TabID>abcdefff-ffff-ffff-ffff-fffffffffffe</TabID>
  104.      <TabType>1</TabType>
  105.      <BrowseTabType>1</BrowseTabType>
  106.      <SortBy>0</SortBy>
  107.      <PageNumber>1</PageNumber>
  108.      <ItemsPerPage>300</ItemsPerPage>
  109.      <MonetizationState>3</MonetizationState>
  110.      <ImageType />
  111.      <EPubPlatform>4</EPubPlatform>
  112.      <Locale>en-NZ</Locale>
  113.   </RequestBody>
  114. </TabRequest>""" % (userid, userkey), headers=subheaders)
  115.  
  116. #print request.text
  117. #you can erase everything after print if you just want to check for books without downloading
  118. matches = re.findall('ContentID="(.*?)"', request.text)
  119. if not matches:
  120.     f = open('C:/Python27/failed_downloads.txt', 'a')
  121.     f.write('\n' + sys.argv[1])
  122.     print('FAILED')
  123. else:
  124.     f =open('C:/Python27/successful_downloads.txt', 'a')
  125.     f.write('\n' + sys.argv[1])
  126.     print('SUCCESSFUL')
  127. for content in matches:
  128.     subheaders = {"Host": "mobile.kobobooks.com",'Content-Type':'text/xml','MobileRequestType':'KEpubRequest'}
  129.     subheaders.update(baseheaders)
  130.     request = a.post("http://mobile.kobobooks.com/75993/mobileRequest.ashx", data = """<?xml version="1.0" encoding="UTF-8"?>
  131.    <KEpubRequest
  132.        xmlns="http://kobobooks.com"
  133.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  134.        xsi:schemaLocation="http://kobobooks.com Requests.xsd">
  135.        <RequestHeader>
  136.            <UserID>%s</UserID>
  137.            <UserKey>%s</UserKey>
  138.            </RequestHeader>
  139.        <RequestBody>
  140.            <ContentType>6</ContentType>
  141.            <ContentID>%s</ContentID>
  142.            <EPubPlatform>4</EPubPlatform>
  143.            <NeedUserInfo>false</NeedUserInfo>
  144.            <NeedDownloadURLs>true</NeedDownloadURLs>
  145.            </RequestBody>
  146.        </KEpubRequest>""" % (userid, userkey, content), headers=subheaders)
  147.     if True:#content == 'f9fc6d6d-5754-455b-94f0-3c872281f8f3':
  148.         #root = ET.fromstring(request.text)
  149.         it = ET.iterparse(StringIO.StringIO(request.text.encode('utf-8')))
  150.         for _, el in it:
  151.             el.tag = el.tag.split('}', 1)[1]  # strip all namespaces
  152.         root = it.root
  153.         url = root.find('./ResponseBody/KePub/EpubInfo/Epub/EpubURLList/URL/DownloadURL').text
  154.         request = a.get(url, headers=baseheaders)
  155.  
  156.         volumekeys = {}
  157.         preuserkey = string.join((a.cookies.get('pwsdid'), a.cookies.get('wsuid')), "")
  158.         uk = SHA256(preuserkey)[32:]
  159.         uk = binascii.a2b_hex(uk)
  160.         enc = AES.new(uk, AES.MODE_ECB)
  161.  
  162.         for pair in root.findall('./ResponseBody/KePub/EpubInfo/Epub/EpubContentKeys/EpubContentKey'):
  163.             key = base64.decodestring(pair.find('./Key').text)
  164.             filename = pair.find('./ContentPath').text
  165.             volumekeys[filename] = enc.decrypt(key)
  166.  
  167.         title = EMAIL
  168.         #root.find('./ResponseBody/KePub/Title').text
  169.  
  170.         zippath = io.BytesIO(request.content)
  171.         z = zipfile.ZipFile(zippath, "r")
  172.         # remove some illegal characters
  173.         outname = "%s.zip" % (re.sub("[^\s\w]", "", title, 0, re.UNICODE))
  174.         if os.path.exists(outname):
  175.             print "SKIPPED:", title
  176.             continue
  177.         zout = zipfile.ZipFile(outname, "w", zipfile.ZIP_DEFLATED)
  178.         for filename in z.namelist():
  179.             #print filename
  180.             # read in and decrypt
  181.             if(filename in volumekeys):
  182.                 # do decrypted version
  183.                 pagekey = volumekeys[filename]
  184.                 penc = AES.new(pagekey, AES.MODE_ECB)
  185.                 contents = RemoveAESPadding(penc.decrypt(z.read(filename)))
  186.                 # need to fix padding
  187.                 zout.writestr(filename, contents)
  188.             else:
  189.                 zout.writestr(filename, z.read(filename))
  190.         zout.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement