diff --git a/Pipfile.lock b/Pipfile.lock deleted file mode 100644 index de335c1..0000000 --- a/Pipfile.lock +++ /dev/null @@ -1,137 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "757b53b537f003a11d2cd5852e5d2e5ee83d6d25452b472e10bba32aadf849e6" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.6" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.python.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "certifi": { - "hashes": [ - "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d", - "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412" - ], - "markers": "python_version >= '3.6'", - "version": "==2022.6.15" - }, - "charset-normalizer": { - "hashes": [ - "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597", - "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df" - ], - "markers": "python_version >= '3'", - "version": "==2.0.12" - }, - "idna": { - "hashes": [ - "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff", - "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d" - ], - "markers": "python_version >= '3'", - "version": "==3.3" - }, - "lxml": { - "hashes": [ - "sha256:04da965dfebb5dac2619cb90fcf93efdb35b3c6994fea58a157a834f2f94b318", - "sha256:0538747a9d7827ce3e16a8fdd201a99e661c7dee3c96c885d8ecba3c35d1032c", - "sha256:0645e934e940107e2fdbe7c5b6fb8ec6232444260752598bc4d09511bd056c0b", - "sha256:079b68f197c796e42aa80b1f739f058dcee796dc725cc9a1be0cdb08fc45b000", - "sha256:0f3f0059891d3254c7b5fb935330d6db38d6519ecd238ca4fce93c234b4a0f73", - "sha256:10d2017f9150248563bb579cd0d07c61c58da85c922b780060dcc9a3aa9f432d", - "sha256:1355755b62c28950f9ce123c7a41460ed9743c699905cbe664a5bcc5c9c7c7fb", - "sha256:13c90064b224e10c14dcdf8086688d3f0e612db53766e7478d7754703295c7c8", - "sha256:1423631e3d51008871299525b541413c9b6c6423593e89f9c4cfbe8460afc0a2", - "sha256:1436cf0063bba7888e43f1ba8d58824f085410ea2025befe81150aceb123e345", - "sha256:1a7c59c6ffd6ef5db362b798f350e24ab2cfa5700d53ac6681918f314a4d3b94", - "sha256:1e1cf47774373777936c5aabad489fef7b1c087dcd1f426b621fda9dcc12994e", - "sha256:206a51077773c6c5d2ce1991327cda719063a47adc02bd703c56a662cdb6c58b", - "sha256:21fb3d24ab430fc538a96e9fbb9b150029914805d551deeac7d7822f64631dfc", - "sha256:27e590352c76156f50f538dbcebd1925317a0f70540f7dc8c97d2931c595783a", - "sha256:287605bede6bd36e930577c5925fcea17cb30453d96a7b4c63c14a257118dbb9", - "sha256:2aaf6a0a6465d39b5ca69688fce82d20088c1838534982996ec46633dc7ad6cc", - "sha256:32a73c53783becdb7eaf75a2a1525ea8e49379fb7248c3eeefb9412123536387", - "sha256:41fb58868b816c202e8881fd0f179a4644ce6e7cbbb248ef0283a34b73ec73bb", - "sha256:4780677767dd52b99f0af1f123bc2c22873d30b474aa0e2fc3fe5e02217687c7", - "sha256:4878e667ebabe9b65e785ac8da4d48886fe81193a84bbe49f12acff8f7a383a4", - "sha256:487c8e61d7acc50b8be82bda8c8d21d20e133c3cbf41bd8ad7eb1aaeb3f07c97", - "sha256:4beea0f31491bc086991b97517b9683e5cfb369205dac0148ef685ac12a20a67", - "sha256:4cfbe42c686f33944e12f45a27d25a492cc0e43e1dc1da5d6a87cbcaf2e95627", - "sha256:4d5bae0a37af799207140652a700f21a85946f107a199bcb06720b13a4f1f0b7", - "sha256:4e285b5f2bf321fc0857b491b5028c5f276ec0c873b985d58d7748ece1d770dd", - "sha256:57e4d637258703d14171b54203fd6822fda218c6c2658a7d30816b10995f29f3", - "sha256:5974895115737a74a00b321e339b9c3f45c20275d226398ae79ac008d908bff7", - "sha256:5ef87fca280fb15342726bd5f980f6faf8b84a5287fcc2d4962ea8af88b35130", - "sha256:603a464c2e67d8a546ddaa206d98e3246e5db05594b97db844c2f0a1af37cf5b", - "sha256:6653071f4f9bac46fbc30f3c7838b0e9063ee335908c5d61fb7a4a86c8fd2036", - "sha256:6ca2264f341dd81e41f3fffecec6e446aa2121e0b8d026fb5130e02de1402785", - "sha256:6d279033bf614953c3fc4a0aa9ac33a21e8044ca72d4fa8b9273fe75359d5cca", - "sha256:6d949f53ad4fc7cf02c44d6678e7ff05ec5f5552b235b9e136bd52e9bf730b91", - "sha256:6daa662aba22ef3258934105be2dd9afa5bb45748f4f702a3b39a5bf53a1f4dc", - "sha256:6eafc048ea3f1b3c136c71a86db393be36b5b3d9c87b1c25204e7d397cee9536", - "sha256:830c88747dce8a3e7525defa68afd742b4580df6aa2fdd6f0855481e3994d391", - "sha256:86e92728ef3fc842c50a5cb1d5ba2bc66db7da08a7af53fb3da79e202d1b2cd3", - "sha256:8caf4d16b31961e964c62194ea3e26a0e9561cdf72eecb1781458b67ec83423d", - "sha256:8d1a92d8e90b286d491e5626af53afef2ba04da33e82e30744795c71880eaa21", - "sha256:8f0a4d179c9a941eb80c3a63cdb495e539e064f8054230844dcf2fcb812b71d3", - "sha256:9232b09f5efee6a495a99ae6824881940d6447debe272ea400c02e3b68aad85d", - "sha256:927a9dd016d6033bc12e0bf5dee1dde140235fc8d0d51099353c76081c03dc29", - "sha256:93e414e3206779ef41e5ff2448067213febf260ba747fc65389a3ddaa3fb8715", - "sha256:98cafc618614d72b02185ac583c6f7796202062c41d2eeecdf07820bad3295ed", - "sha256:9c3a88d20e4fe4a2a4a84bf439a5ac9c9aba400b85244c63a1ab7088f85d9d25", - "sha256:9f36de4cd0c262dd9927886cc2305aa3f2210db437aa4fed3fb4940b8bf4592c", - "sha256:a60f90bba4c37962cbf210f0188ecca87daafdf60271f4c6948606e4dabf8785", - "sha256:a614e4afed58c14254e67862456d212c4dcceebab2eaa44d627c2ca04bf86837", - "sha256:ae06c1e4bc60ee076292e582a7512f304abdf6c70db59b56745cca1684f875a4", - "sha256:b122a188cd292c4d2fcd78d04f863b789ef43aa129b233d7c9004de08693728b", - "sha256:b570da8cd0012f4af9fa76a5635cd31f707473e65a5a335b186069d5c7121ff2", - "sha256:bcaa1c495ce623966d9fc8a187da80082334236a2a1c7e141763ffaf7a405067", - "sha256:bd34f6d1810d9354dc7e35158aa6cc33456be7706df4420819af6ed966e85448", - "sha256:be9eb06489bc975c38706902cbc6888f39e946b81383abc2838d186f0e8b6a9d", - "sha256:c4b2e0559b68455c085fb0f6178e9752c4be3bba104d6e881eb5573b399d1eb2", - "sha256:c62e8dd9754b7debda0c5ba59d34509c4688f853588d75b53c3791983faa96fc", - "sha256:c852b1530083a620cb0de5f3cd6826f19862bafeaf77586f1aef326e49d95f0c", - "sha256:d9fc0bf3ff86c17348dfc5d322f627d78273eba545db865c3cd14b3f19e57fa5", - "sha256:dad7b164905d3e534883281c050180afcf1e230c3d4a54e8038aa5cfcf312b84", - "sha256:e5f66bdf0976ec667fc4594d2812a00b07ed14d1b44259d19a41ae3fff99f2b8", - "sha256:e8f0c9d65da595cfe91713bc1222af9ecabd37971762cb830dea2fc3b3bb2acf", - "sha256:edffbe3c510d8f4bf8640e02ca019e48a9b72357318383ca60e3330c23aaffc7", - "sha256:eea5d6443b093e1545ad0210e6cf27f920482bfcf5c77cdc8596aec73523bb7e", - "sha256:ef72013e20dd5ba86a8ae1aed7f56f31d3374189aa8b433e7b12ad182c0d2dfb", - "sha256:f05251bbc2145349b8d0b77c0d4e5f3b228418807b1ee27cefb11f69ed3d233b", - "sha256:f1be258c4d3dc609e654a1dc59d37b17d7fef05df912c01fc2e15eb43a9735f3", - "sha256:f9ced82717c7ec65a67667bb05865ffe38af0e835cdd78728f1209c8fffe0cad", - "sha256:fe17d10b97fdf58155f858606bddb4e037b805a60ae023c009f760d8361a4eb8", - "sha256:fe749b052bb7233fe5d072fcb549221a8cb1a16725c47c37e42b0b9cb3ff2c3f" - ], - "index": "pypi", - "version": "==4.9.1" - }, - "requests": { - "hashes": [ - "sha256:6c1246513ecd5ecd4528a0906f910e8f0f9c6b8ec72030dc9fd154dc1a6efd24", - "sha256:b8aa58f8cf793ffd8782d3d8cb19e66ef36f7aba4353eec859e74678b01b07a7" - ], - "index": "pypi", - "version": "==2.26.0" - }, - "urllib3": { - "hashes": [ - "sha256:39fb8672126159acb139a7718dd10806104dec1e2f0f6c88aab05d17df10c8d4", - "sha256:f57b4c16c62fa2760b7e3d97c35b255512fb6b59a259730f36ba32ce9f8e342f" - ], - "index": "pypi", - "version": "==1.26.6" - } - }, - "develop": {} -} diff --git a/register_user.py b/register_user.py deleted file mode 100644 index 93f3fc6..0000000 --- a/register_user.py +++ /dev/null @@ -1,153 +0,0 @@ -import re -import requests -import safaribooks - -REGISTER_URL = safaribooks.SAFARI_BASE_URL + "/register/" -CHECK_EMAIL = safaribooks.SAFARI_BASE_URL + "/check-email-availability/" -CHECK_PWD = safaribooks.SAFARI_BASE_URL + "/check-password/" - -# DEBUG -USE_PROXY = False -PROXIES = {"https": "https://127.0.0.1:8080"} - -CSRF_TOKEN_RE = re.compile(r"(?<=name='csrfmiddlewaretoken' value=')([^']+)") - - -class Register: - def __init__(self, email, password, first_name, second_name, country="US", referrer="podcast"): - self.email = email - self.password = password - self.first_name = first_name - self.second_name = second_name - self.country = country - self.referrer = referrer - - self.csrf = None - - self.session = requests.Session() - if USE_PROXY: # DEBUG - self.session.proxies = PROXIES - self.session.verify = False - - self.session.headers.update(safaribooks.SafariBooks.HEADERS) - self.session.headers.update({ - "X-Requested-With": "XMLHttpRequest", - "Referer": REGISTER_URL - }) - - self.register() - - def handle_cookie_update(self, set_cookie_headers): - for morsel in set_cookie_headers: - # Handle Float 'max-age' Cookie - if safaribooks.SafariBooks.COOKIE_FLOAT_MAX_AGE_PATTERN.search(morsel): - cookie_key, cookie_value = morsel.split(";")[0].split("=") - self.session.cookies.set(cookie_key, cookie_value) - - def requests_provider(self, url, is_post=False, data=None, perform_redirect=True, check_200=True, **kwargs): - try: - response = getattr(self.session, "post" if is_post else "get")( - url, - data=data, - allow_redirects=False, - **kwargs - ) - - self.handle_cookie_update(response.raw.headers.getlist("Set-Cookie")) - - except (requests.ConnectionError, requests.ConnectTimeout, requests.RequestException) as request_exception: - print("Error: ", str(request_exception)) - return 0 - - if response.is_redirect and perform_redirect: - return self.requests_provider(response.next.url, is_post, None, perform_redirect, check_200, **kwargs) - - if check_200 and response.status_code != 200: - print("Invalid response code:\n", response.text) - return 0 - - return response - - def register(self): - # Take first cookie + csrf - response = self.requests_provider(REGISTER_URL) - if response == 0: - print("Error 0x1: unable to reach registration page!") - exit(1) - - if "csrfmiddlewaretoken' value='" not in response.text: - print("Error 0x2: CSRF token not present") - exit(1) - - csrf_search = CSRF_TOKEN_RE.findall(response.text) - if not len(csrf_search): - print("Error 0x3: CSRF token RE error") - exit(1) - - self.csrf = csrf_search[0] - - # Check user validity - response = self.requests_provider(CHECK_EMAIL, params={"email": self.email}) - if response == 0: - print("Error 0x4: unable to check email!") - exit(1) - - response_dict = response.json() - if not response_dict["success"]: - print("Error 0x5:", response_dict["message"]) - exit(1) - - # Check password validity - response = self.requests_provider(CHECK_PWD, is_post=True, data={ - "csrfmiddlewaretoken": self.csrf, - "password1": self.password, - "field_name": "password1" - }) - if response == 0: - print("Error 0x6: unable to check password!") - exit(1) - - response_dict = response.json() - if not response_dict["valid"]: - print("Error 0x7:", response_dict["msg"]) - exit(1) - - # Register - response = self.requests_provider(REGISTER_URL, is_post=True, data={ - "next": "", - "trial_length": 10, - "csrfmiddlewaretoken": self.csrf, - "first_name": self.first_name, - "last_name": self.second_name, - "email": self.email, - "password1": self.password, - "country": self.country, - "referrer": "podcast", - "recently_viewed_bits": "[]" - }, check_200=False) - if response == 0: - print("Error 0x8: unable to register!") - exit(1) - - elif response.status_code != 201: - print("Error: 0x9: invalid status code while registering!") - exit(1) - - print("[*] Account registered: \nEMAIL: %s\nPASSWORD: %s" % (self.email, self.password)) - return - - -if __name__ == "__main__": - import sys - if len(sys.argv) < 3: - print("[!] Error: too few arguments.\nRun `register_user.py EMAIL PASSWORD`.") - exit(1) - - elif len(sys.argv) > 3: - print("[!] Error: too much arguments, try to enclose the string with quote '\"'.") - exit(1) - - FIRST_NAME = "Safari" - SECOND_NAME = "Download" - - Register(sys.argv[1], sys.argv[2], FIRST_NAME, SECOND_NAME) diff --git a/retrieve_cookies.py b/retrieve_cookies.py new file mode 100644 index 0000000..28ad669 --- /dev/null +++ b/retrieve_cookies.py @@ -0,0 +1,29 @@ +import json + +# See: https://github.com/lorenzodifuccia/safaribooks/issues/358 + +try: + from safaribooks import COOKIES_FILE +except ImportError: + COOKIES_FILE = "cookies.json" + +try: + import browser_cookie3 +except ImportError: + raise ImportError("Please run this program via: uv run --with browser_cookie3 python retrieve_cookies.py") + +def get_oreilly_cookies(): + cj = browser_cookie3.load() + cookies = {} + for c in cj: + cookies[c.name] = c.value + return cookies + +def main(): + cookies = get_oreilly_cookies() + with open(COOKIES_FILE, "w") as f: + json.dump(cookies, f) + print(f"Cookies saved to {COOKIES_FILE}") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/sso_cookies.py b/sso_cookies.py deleted file mode 100644 index 862cc5b..0000000 --- a/sso_cookies.py +++ /dev/null @@ -1,42 +0,0 @@ -""" -Script for SSO support, saves and converts the cookie string retrieved by the browser. -Please follow: -- https://github.com/lorenzodifuccia/safaribooks/issues/26 -- https://github.com/lorenzodifuccia/safaribooks/issues/150#issuecomment-555423085 -- https://github.com/lorenzodifuccia/safaribooks/issues/2#issuecomment-367726544 - - -Thanks: @elrob, @noxymon -""" - -import json -import safaribooks - - -def transform(cookies_string): - cookies = {} - for cookie in cookies_string.split("; "): - key, value = cookie.split("=", 1) - cookies[key] = value - - print(cookies) - json.dump(cookies, open(safaribooks.COOKIES_FILE, 'w')) - print("\n\nDone! Cookie Jar saved into `cookies.json`. " - "Now you can run `safaribooks.py` without the `--cred` argument...") - - -USAGE = "\n\n[*] Please use this command putting as argument the cookies retrieved by your browser.\n" + \ - "[+] In order to do so, please follow these steps: \n" + \ - "https://github.com/lorenzodifuccia/safaribooks/issues/150#issuecomment-555423085\n" - -if __name__ == "__main__": - import sys - if len(sys.argv) < 2: - print("[!] Error: too few arguments." + USAGE) - exit(1) - - elif len(sys.argv) > 2: - print("[!] Error: too much arguments, try to enclose the string with quote '\"'." + USAGE) - exit(1) - - transform(sys.argv[1])