예제 #1
0
파일: shift.py 프로젝트: maxadss/autoshift
    def __redeem_form(self, data):
        """Redeem a code with given form data"""
        # cache old reward list
        self.old_rewards = self.__query_rewards()

        the_url = "{}/code_redemptions".format(base_url)
        headers = {"Referer": "{}/new".format(the_url)}
        r = self.client.post(the_url,
                             data=data,
                             headers=headers,
                             allow_redirects=False)
        _L.debug("{} {} {}".format(r.request.method, r.url, r.status_code))
        status, redirect = self.__check_redemption_status(r)
        # did we visit /code_redemptions/...... route?
        redemption = False
        # keep following redirects
        while status == Status.REDIRECT:
            if "code_redemptions/" in redirect:
                redemption = True
            _L.debug("redirect to '{}'".format(redirect))
            r2 = self.client.get(redirect)
            status, redirect = self.__check_redemption_status(r2)

        # workaround for new SHiFT website.
        # it doesn't tell you to launch a "SHiFT-enabled title" anymore
        if status == Status.NONE:
            if redemption:
                status = Status.REDEEMED
                redirect = "Already Redeemed"
            else:
                status = Status.TRYLATER
                redirect = "To continue to redeem SHiFT codes, please launch a SHiFT-enabled title first!"  # noqa
        return status, redirect
예제 #2
0
    def __get_redemption_form(self, code, platform):
        """Get Form data for code redemption"""
        the_url = "{}/code_redemptions/new".format(base_url)
        status_code, token = self.__get_token(the_url)
        if not token:
            _L.debug("no token")
            return False, status_code, "Could not retrieve Token"

        r = self.client.get("{base_url}/entitlement_offer_codes?code={code}"
                            .format(base_url=base_url, **locals()),
                            headers=json_headers(token))

        _L.debug("{} {} {}".format(r.request.method, r.url, r.status_code))
        soup = BSoup(r.text, "html.parser")
        if not soup.find("form", class_="new_archway_code_redemption"):
            return False, r.status_code, r.text.strip()

        inp = soup.find_all("input", attrs=dict(name="authenticity_token"))
        form_code = soup.find_all(id="archway_code_redemption_code")
        check = soup.find_all(id="archway_code_redemption_check")
        service = soup.find_all(id="archway_code_redemption_service")

        ind = None
        for i, s in enumerate(service):
            if platform in s["value"]:
                ind = i
                break
        if (ind is None):
            return False, r.status_code, "This code is not available for your platform"

        form_data = {"authenticity_token": inp[ind]["value"],
                     "archway_code_redemption[code]": form_code[ind]["value"],
                     "archway_code_redemption[check]": check[ind]["value"],
                     "archway_code_redemption[service]": service[ind]["value"]}
        return True, r.status_code, form_data
예제 #3
0
파일: shift.py 프로젝트: maxadss/autoshift
    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
예제 #4
0
파일: auto.py 프로젝트: bawaaaaah/autoshift
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
예제 #5
0
    def __get_redemption_form(self, code):
        """Get Form data for code redemption"""
        the_url = "{}/code_redemptions/new".format(base_url)
        status_code, token = self.__get_token(the_url)
        if not token:
            _L.debug("no token")
            return False, status_code, "Could not retrieve Token"

        r = self.client.get("{base_url}/entitlement_offer_codes?code={code}"
                            .format(base_url=base_url, **locals()),
                            headers=json_headers(token))
        soup = BSoup(r.text, "html.parser")
        if not soup.find("form", class_="new_archway_code_redemption"):
            return False, r.status_code, r.text.strip()

        inp = soup.find("input", attrs=dict(name="authenticity_token"))
        form_code = soup.find(id="archway_code_redemption_code")["value"]
        check = soup.find(id="archway_code_redemption_check")["value"]
        service = soup.find(id="archway_code_redemption_service")["value"]

        form_data = {"authenticity_token": inp["value"],
                     "archway_code_redemption[code]": form_code,
                     "archway_code_redemption[check]": check,
                     "archway_code_redemption[service]": service}
        return True, r.status_code, form_data
예제 #6
0
 def redeem(self, code, platform):
     found, status_code, form_data = self.__get_redemption_form(
         code, platform)
     # the expired message comes from even wanting to redeem
     if not found and form_data == "This SHiFT code has already been redeemed":
         status = Status.REDEEMED
         result = "Already Redeemed"
     elif not found:
         # entered key was invalid
         if status_code == 500:
             return Status.INVALID
         # entered key expired by now
         if "expired" in form_data:
             return Status.EXPIRED
         if "not available" in form_data:
             return Status.INVALID
         # unknown
         _L.error(form_data)
         return Status.UNKNOWN
     else:
         # the key is valid and all.
         status, result = self.__redeem_form(form_data)
     self.last_status = status
     _L.debug("{}: {}".format(Status(status), result))
     return status
예제 #7
0
파일: shift.py 프로젝트: maxadss/autoshift
    def __get_token(self, url_or_reply):
        """Get CSRF-Token from given URL"""
        if type(url_or_reply) == str:
            r = self.client.get(url_or_reply)
            _L.debug("{} {} {}".format(r.request.method, r.url, r.status_code))
        else:
            r = url_or_reply

        soup = BSoup(r.text, "html.parser")
        meta = soup.find("meta", attrs=dict(name="csrf-token"))
        if not meta:
            return r.status_code, None
        return r.status_code, meta["content"]
예제 #8
0
def parse_bl2blps(game, platform):
    """Get all Keys from orcz"""
    key_urls = {
        "bl": "http://orcz.com/Borderlands:_Golden_Key",
        "bl2": "http://orcz.com/Borderlands_2:_Golden_Key",
        "blps": "http://orcz.com/Borderlands_Pre-Sequel:_Shift_Codes",
        "bl3": "http://orcz.com/Borderlands_3:_Golden_Key",
        "ttw": "http://orcz.com/Tiny_Tina%27s_Wonderlands:_Shift_Codes"
    }

    def check(key):
        """Check if key is expired (return None if so)"""
        ret = None
        span = key.find("span")
        if (not span) or (not span.get("style")) or ("black" in span["style"]):
            ret = key.text.strip()

            # must be of format ABCDE-FGHIJ-KLMNO-PQRST
            if ret.count("-") != 4:
                return None
            spl = ret.split("-")
            spl = [len(el) == 5 for el in spl]
            if not all(spl):
                return None

        return ret

    r = requests.get(key_urls[game])
    soup = BSoup(r.text, "lxml")
    table = soup.find("table")
    rows = table.find_all("tr")[1:]
    for row in rows:
        cols = row.find_all("td")
        desc = cols[1].text.strip()
        codes = [None, None, None]
        for i in range(4, 7):
            try:
                codes[i - 4] = check(cols[i])
            except Exception as e:  # noqa
                _L.debug(e)
                pass

        codes.insert(1, None)

        for i in range(len(codes)):
            if codes[i]:
                the_platform = platforms[i]
                if platforms[i] in ["steam", "epic"]:
                    the_platform = "pc"
                yield desc, codes[i], the_platform, game
예제 #9
0
파일: query.py 프로젝트: Gyran/autoshift
def insert(desc, code, platform, game):
    """Insert Key"""
    el = c.execute("""SELECT * FROM keys
                   WHERE platform = ?
                   AND key = ?
                   AND game = ?""",
                   (platform, code, game))
    if el.fetchone():
        return
    _L.debug("== inserting {} Key '{}' for {} ==".format(game.upper(), code,
                                                         platform.upper()))
    c.execute("INSERT INTO keys(description, key, platform, game, redeemed) "
              "VAlUES (?,?,?,?,0)", (desc, code, platform, game))
    conn.commit()
예제 #10
0
 def __login(self, user, pw):
     """Login with user/pw"""
     the_url = "{}/home".format(base_url)
     status_code, token = self.__get_token(the_url)
     if not token:
         return None
     login_data = {"authenticity_token": token,
                   "user[email]": user,
                   "user[password]": pw}
     headers = {"Referer": the_url}
     r = self.client.post("{}/sessions".format(base_url),
     # r = self.client.post("{}/sessions".format("http://127.0.0.1:8000"),
                          data=login_data,
                          headers=headers)
     _L.debug("{} {} {}".format(r.request.method, r.url, r.status_code))
     return r
예제 #11
0
    def redeem(self, code):
        found, status_code, form_data = self.__get_redemption_form(code)
        # the expired message comes from even wanting to redeem
        if not found:
            # entered key was invalid
            if status_code == 500:
                return Status.INVALID
            # entered key expired by now
            if "expired" in form_data:
                return Status.EXPIRED
            # unknown
            _L.error(form_data)
            return Status.UNKNOWN

        # the key is valid and all.
        status, result = self.__redeem_form(form_data)
        self.last_status = status
        _L.debug("{}: {}".format(Status(status), result))
        return status
예제 #12
0
파일: auto.py 프로젝트: bawaaaaah/autoshift

if __name__ == "__main__":
    import os
    # only print license text on first use
    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'))