Skip to content

Instantly share code, notes, and snippets.

@Earthnuker Earthnuker/BL_SHiFTer.py Secret
Created Oct 6, 2019

Embed
What would you like to do?
Automatically scrape and submit SHiFT codes for borderlands
import mechanicalsoup
from getpass import getpass
import requests as RQ
from bs4 import BeautifulSoup as BS
from concurrent.futures import ThreadPoolExecutor,as_completed
import time
import sys
import re
import json
from pprint import pformat
from tqdm import tqdm
import os
responses=[]
if os.path.isfile("responses.json"):
pass
def fetch_codes():
shift_codes=[]
shift_re=re.compile(r"[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}-[A-Z0-9]{5}")
shift_urls=["http://orcz.com/Borderlands:_Golden_Key",
"http://orcz.com/Borderlands_2:_Golden_Key",
"http://orcz.com/Borderlands_Pre-Sequel:_Shift_Codes",
"http://orcz.com/Borderlands_3:_Shift_Codes",
]
for url in shift_urls:
soup=BS(RQ.get(url).text,'lxml').find_all('table',{'class':'wikitable'})
for table in soup:
for td in table.find_all('td'):
shift_codes+=shift_re.findall(td.text)
return sorted(set(shift_codes))
AUTH_HEADERS={
'Host': "api.2k.com",
'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0",
'Accept': "*/*",
'Accept-Language': "en-US,en;q=0.5",
'Accept-Encoding': "gzip, deflate, br",
'Access-Control-Request-Method': "POST",
'Access-Control-Request-Headers': "content-type",
'Referer': "https://borderlands.com/en-US/",
'Origin': "https://borderlands.com",
'Connection': "keep-alive",
'Pragma': "no-cache",
'Cache-Control': "no-cache",
'cache-control': "no-cache",
}
def cors_rq(method,url,*args,**kwargs):
opts=browser.request('OPTIONS',url,*args,headers=AUTH_HEADERS,**kwargs)
opts.raise_for_status()
resp=browser.request(method,url,*args,headers=AUTH_HEADERS,**kwargs)
return resp
def code_info(shift_code):
info_url='https://api.2k.com/borderlands/code/{}/info'.format(shift_code)
return cors_rq('GET',info_url).json()
def redeem(code):
redeem_url="https://api.2k.com/borderlands/code/{code}/redeem/{offer_service}".format(**code)
while True:
resp=cors_rq('POST',redeem_url)
info=resp.json()
if info.get('error',{}).get('code')!='RATE_LIMITED':
break
time.sleep(300)
if info.get('message')=='REDEMPTION_QUEUED':
job_id=info.get('job_id')
if job_id:
delay=info['max_wait_milliseconds']/1000
time.sleep(delay)
resp=cors_rq('GET','https://api.2k.com/borderlands/code/{0}/job/{1}'.format(code['code'],job_id))
return {'url':redeem_url,'code':code,'result':resp.text}
return info
browser=mechanicalsoup.StatefulBrowser(user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0')
browser.open("https://borderlands.com/en-US/")
email=input("E-Mail: ")
passwd=getpass()
resp=cors_rq('POST','https://api.2k.com/borderlands/users/authenticate',json={"username":email,"password":passwd})
AUTH_HEADERS['X-Session']=resp.headers['X-SESSION-SET']
account_info=resp.json()
acct_key=[]
for game in account_info['playedGames']:
for platform in game['platforms']:
acct_key.append((platform['service'],game['title']))
def can_redeem(code,acct_key):
if not code.get('is_active'):
return False
if (code['offer_service'],code['offer_title']) not in acct_key:
return False
return True
codes=[]
with ThreadPoolExecutor(32) as pool:
jobs=[]
for code in tqdm(fetch_codes(),ascii=True,desc="Submiting Jobs"):
jobs.append(pool.submit(code_info,code))
pbar=tqdm(as_completed(jobs),total=len(jobs),ascii=True,desc="Fetching infos")
for code_info in pbar:
code_info=code_info.result()
if not code_info:
continue
if not 'entitlement_offer_codes' in code_info:
continue
codes+=code_info['entitlement_offer_codes']
codes=list(filter(lambda c:can_redeem(c,acct_key),codes))
responses=[]
for code in codes:
resp=redeem(code)
responses.append(resp)
print(pformat(resp))
print("="*20)
json.dump(responses,open("responses.json","w"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.