def __check_redemption_status(self, r): """Check redemption""" import json from time import sleep if (r.status_code == 302): return Status.REDIRECT, r.headers["location"] get_status, url, fallback = self.__get_redemption_status(r) if get_status: status_code, token = self.__get_token(r) cnt = 0 while True: if cnt > 5: return Status.REDIRECT, fallback _L.info(get_status) # wait 500 _L.debug("get " + "{}/{}".format(base_url, url)) raw_json = self.client.get("{}/{}".format(base_url, url), allow_redirects=False, headers=json_headers(token)) data = json.loads(raw_json.text) if "text" in data: get_status = self.__get_status(data["text"]) return get_status sleep(0.5) cnt += 1 return Status.NONE, None
def redeem(key): """Redeem key and set as redeemed if successfull""" messages = { Status.SUCCESS: "Redeemed {key.description}", Status.EXPIRED: "This code expired by now.. ({key.description})", Status.REDEEMED: "Already redeemed {key.description}", Status.INVALID: "The code `{key.key}` is invalid", Status.TRYLATER: "Please launch a SHiFT-enabled title or wait 1 hour.", Status.UNKNOWN: "A unknown Error occured", Status.NONE: "Something unexpected happened.." } _L.debug("Trying to redeem {} ({})".format(key.description, key.key)) status = client.redeem(key.key) _L.debug("Status: {}".format(Status(status))) # set redeemed status if status in (Status.SUCCESS, Status.REDEEMED, Status.EXPIRED, Status.INVALID): query.set_redeemed(key) # notify user _L.info(messages[status].format(**locals())) return status == Status.SUCCESS
def main(args): global client import re if not client: client = ShiftClient() g_reg = re.compile(r"^(\d+).*gold.*", re.I) query.open_db() # query all keys all_keys = query_keys(args.games, args.platforms) # redeem 0 golden keys but only golden??... duh if not args.limit and args.golden: _L.info("Not redeeming anything ...") return # now redeem for game in all_keys.keys(): for platform in all_keys[game].keys(): t_keys = all_keys[game][platform] for key in t_keys: if key.redeemed: # we could query only unredeemed keys # but we have them already so it doesn't matter continue num_g_keys = 0 # number of golden keys in this code m = g_reg.match(key.description) # skip keys we don't want if ((args.golden and not m) or (args.non_golden and m)): continue if m: num_g_keys = int(m.group(1)) # skip golden keys if we reached the limit if args.limit <= 0: continue # skip if this code has too many golden keys if (args.limit - num_g_keys) < 0: continue redeemed = redeem(key) if redeemed: args.limit -= num_g_keys _L.info("Redeeming another {} Keys".format(args.limit)) else: # don't spam if we reached the hourly limit if client.last_status == Status.TRYLATER: return query.close_db()
def __init__(self, user=None, pw=None): from os import path self.client = requests.session() self.last_status = Status.NONE self.cookie_file = path.join(DIRNAME, "data", ".cookies.save") # try to load cookies. Query for login data if not present if not self.__load_cookie(): print("First time usage: Login to your SHiFT account...") if not user: user = input("Username: "******"Password: "******"Login Successful") else: exit(0)
if not os.path.exists(os.path.join(DIRNAME, ".cookies.save")): print(LICENSE_TEXT) # build argument parser parser = setup_argparser() args = parser.parse_args() _L.setLevel(INFO) if args.verbose: _L.setLevel(DEBUG) _L.debug("Debug mode on") # always execute at least once main(args) # scheduling will start after first trigger (so in an hour..) if args.schedule: _L.info("Scheduling to run once an hour") from apscheduler.schedulers.blocking import BlockingScheduler scheduler = BlockingScheduler() # fire every 1h5m # (5min safe margin because it somtimes fires a few seconds too early) scheduler.add_job(main, "interval", args=(args, ), hours=1, minutes=5) print('Press Ctrl+{} to exit'.format('Break' if os.name == 'nt' else 'C')) try: scheduler.start() except (KeyboardInterrupt, SystemExit): pass