def test_sqlite3_operational_error(mocker): session = urlquick.Session() mocked = mocker.patch.object(session.cache_adapter, "conn", autospec=True) mocked.execute.side_effect = sqlite3.OperationalError("Boom!") with pytest.raises(sqlite3.OperationalError): session.cache_adapter.wipe()
def test_delete(self, requests_mock): url = 'https://www.test.com/1' mocked = requests_mock.get(url, body=b"data") session = urlquick.Session() ret = session.get('https://www.test.com/1') assert mocked.called assert ret.from_cache is False assert ret.content == b"data" mocked.reset_stats() # Build Request object req = requests.PreparedRequest() req.prepare_method("GET") req.prepare_url(url, None) req.prepare_headers(None) req.prepare_body(b"", None, None) # Test del_cache urlhash = urlquick.hash_url(req) session.cache_adapter.del_cache(urlhash) ret = session.get('https://www.test.com/1') assert mocked.called assert ret.from_cache is False assert ret.content == b"data"
def __init__(self, max_results=50, pretty_print=False): self.req_session = urlquick.Session() self.req_session.headers["referer"] = "http://www.codequick.com/" self.req_session.params = { "maxResults": str(max_results), "prettyPrint": str(pretty_print).lower(), "key": "AIzaSyD_guosGuZjoQLWIZdJzYzYEn3Oy8VOUgs" }
def test_request_header_none(requests_mock): shutil.rmtree(urlquick.CACHE_LOCATION, ignore_errors=True) mocked = requests_mock.get('https://www.test.com/test/542', body=b"data") session = urlquick.Session() ret = session.request("GET", 'https://www.test.com/test/542', None, None, None) assert mocked.called assert ret.content == b"data"
def test_true_error(self, requests_mock): mocked = requests_mock.get('https://www.test.com/1', body=b"data", status=404) session = urlquick.Session(raise_for_status=True) with pytest.raises(urlquick.HTTPError): session.get('https://www.test.com/1') assert mocked.called
def test_true_normal(self, requests_mock): mocked = requests_mock.get('https://www.test.com/1', body=b"data", status=200) session = urlquick.Session(raise_for_status=True) ret = session.get('https://www.test.com/1') assert mocked.called assert ret.from_cache is False assert ret.status_code == 200 assert ret.content == b"data"
def test_false_error(self, requests_mock): mocked = requests_mock.get('https://www.test.com/1', body=b"data", status=404) session = urlquick.Session() ret = session.get('https://www.test.com/1') assert mocked.called assert ret.from_cache is False assert ret.status_code == 404 assert ret.content == b"data"
def test_cache_unknown_error(mocker, requests_mock): """Test that get_cache will clear the cache on error.""" shutil.rmtree(urlquick.CACHE_LOCATION, ignore_errors=True) mocked_url_1 = requests_mock.get('https://www.test.com/1', body=b"test1") mocked_url_2 = requests_mock.get('https://www.test.com/2', body=b"test2") session = urlquick.Session() # Check that the mocked url is called ret = session.get('https://www.test.com/1') assert mocked_url_1.called assert ret.from_cache is False assert ret.content == b"test1" mocked_url_1.reset_stats() ret = session.get('https://www.test.com/2') assert mocked_url_2.called assert ret.from_cache is False assert ret.content == b"test2" mocked_url_2.reset_stats() # Should be cached now so mocked should not be called ret = session.get('https://www.test.com/1') assert not mocked_url_1.called assert ret.from_cache is True assert ret.content == b"test1" mocked_url_1.reset_stats() ret = session.get('https://www.test.com/2') assert not mocked_url_2.called assert ret.from_cache is True assert ret.content == b"test2" mocked_url_2.reset_stats() # Mock CacheRecord to raise ValueError mocked = mocker.patch.object(urlquick, "CacheRecord") mocked.side_effect = ValueError("normal error") # For normal errors only the current cache item # will be remove but all the rest will stay ret = session.get('https://www.test.com/1') assert mocked_url_1.called assert ret.from_cache is False assert ret.content == b"test1" mocker.stopall() # This request should not be called again ret = session.get('https://www.test.com/2') assert not mocked_url_2.called assert ret.from_cache is True assert ret.content == b"test2"
def get_live_url(plugin, item_id, video_id, item_dict): resp = urlquick.get(URL_LIVE) player_id = re.compile(r'\&player\=(.*?)\"').findall(resp.text)[0] session_urlquick = urlquick.Session(allow_redirects=False) resp2 = session_urlquick.get(URL_INFOMANIAK_LIVE % player_id) location_url = resp2.headers['Location'] resp3 = urlquick.get(location_url.replace( 'infomaniak.com/', 'infomaniak.com/playerConfig.php'), max_age=-1) json_parser = json.loads(resp3.text) stream_url = '' for stram_datas in json_parser['data']['integrations']: if 'hls' in stram_datas['type']: stream_url = stram_datas['url'] return stream_url
def test_wipe(self, requests_mock): mocked = requests_mock.get('https://www.test.com/1', body=b"data") session = urlquick.Session() ret = session.get('https://www.test.com/1') assert mocked.called assert ret.from_cache is False assert ret.content == b"data" mocked.reset_stats() # Wipe the cache clean session.cache_adapter.wipe() ret = session.get('https://www.test.com/1') assert mocked.called assert ret.from_cache is False assert ret.content == b"data"
def test_cache_unsupported_protocol(mocker, requests_mock): """Test that get_cache will clear the cache on error.""" shutil.rmtree(urlquick.CACHE_LOCATION, ignore_errors=True) mocked_url_1 = requests_mock.get('https://www.test.com/1', body=b"test1") mocked_url_2 = requests_mock.get('https://www.test.com/2', body=b"test2") session = urlquick.Session() # Check that the mocked url is called ret = session.get('https://www.test.com/1') assert mocked_url_1.called assert ret.from_cache is False assert ret.content == b"test1" mocked_url_1.reset_stats() ret = session.get('https://www.test.com/2') assert mocked_url_2.called assert ret.from_cache is False assert ret.content == b"test2" mocked_url_2.reset_stats() # Should be cached now so mocked should not be called ret = session.get('https://www.test.com/1') assert not mocked_url_1.called assert ret.from_cache is True assert ret.content == b"test1" mocked_url_1.reset_stats() ret = session.get('https://www.test.com/2') assert not mocked_url_2.called assert ret.from_cache is True assert ret.content == b"test2" mocked_url_2.reset_stats() # Mock CacheRecord to raise ValueError mocked = mocker.patch("urlquick.CacheRecord") mocked.side_effect = ValueError("unsupported pickle protocol") # For a unsupported pickle protocol the whole cache is wiped so both should be called ret = session.get('https://www.test.com/1') assert mocked_url_1.called assert ret.from_cache is False assert ret.content == b"test1" mocked.stopall() # This should be called again ret = session.get('https://www.test.com/2') assert mocked_url_2.called assert ret.from_cache is False assert ret.content == b"test2"
def test_session_send(requests_mock): shutil.rmtree(urlquick.CACHE_LOCATION, ignore_errors=True) url = 'https://www.test.com/1' mocked = requests_mock.get(url, body=b"data") session = urlquick.Session() # Build Request object req = requests.PreparedRequest() req.prepare_method("GET") req.prepare_url(url, None) req.prepare_headers(None) req.prepare_body(b"", None, None) ret = session.send(req) assert mocked.called assert ret.content == b"data"
def get_video_url(plugin, item_id, video_url, content_id, download_mode=False, **kwargs): session = urlquick.Session() resp = session.get(video_url, headers={'User-Agent': web_utils.get_random_ua()}, max_age=-1) video_id = re.compile( r'dataMediaId\"\:\"(.*?)\"').findall(resp.text)[0] resp2 = session.get(URL_STREAM_DATAS % video_id, headers={'User-Agent': web_utils.get_random_ua()}, max_age=-1) json_parser2 = json.loads(resp2.text) url_stream = '' for stream_datas in json_parser2["dls"]: if 'hls' in stream_datas["format"]: url_stream = stream_datas["stream"] datas = { 'oid': 'bitban_api', 'eid': '/api/greenBox?contentId=%s&platform=mtweb' % content_id } resp3 = session.get(URL_MAB, params=datas) json_parser3 = json.loads(resp3.text) session.get(json_parser2["cerbero"] + '/geo', headers={'User-Agent': web_utils.get_random_ua()}, max_age=-1) payload = { 'bbx': json_parser2["bbx"], 'gbx': json_parser3["gbx"] } resp4 = session.post(json_parser2["cerbero"], json=payload, headers={'User-Agent': web_utils.get_random_ua()}, max_age=-1) json_parser4 = json.loads(resp4.text) return url_stream + '?' + json_parser4["tokens"]["2"]["cdn"]
def request(self): """ A urlquick.session object. This is used for requesting online resources. It is very similar to requests.session but with built-in caching support. .. seealso:: The urlquick documentation can be found at.\n http://urlquick.readthedocs.io/en/stable/ :example: >>> from codequick import Route >>> >>> @Route.register >>> def root(plugin): >>> html = plugin.request.get("http://example.com/index.html") >>> root_element = html.parse() >>> print(root_element) >>> "xml.etree.ElementTree.Element" """ return urlquick.Session()
def get_live_url(plugin, item_id, video_id, **kwargs): resp = urlquick.get(URL_ROOT, headers={'User-Agent': web_utils.get_random_ua()}, max_age=-1) player_id = re.compile(r'\;player\=(.*?)\'').findall(resp.text)[0] session_urlquick = urlquick.Session(allow_redirects=False) resp2 = session_urlquick.get( URL_STREAM % player_id, headers={'User-Agent': web_utils.get_random_ua()}, max_age=-1) location_url = resp2.headers['Location'] resp3 = urlquick.get(location_url.replace( 'infomaniak.com/', 'infomaniak.com/playerConfig.php'), max_age=-1) json_parser = json.loads(resp3.text) stream_url = '' for stram_datas in json_parser['data']['integrations']: if 'hls' in stram_datas['type']: stream_url = stram_datas['url'] return stream_url
def test_sqlite3_error(mocker): mocker.patch("sqlite3.connect", side_effect=sqlite3.Error("Boom!")) with pytest.raises(urlquick.CacheError): urlquick.Session()
def __init__(self): self.session = urlquick.Session() self.session.headers.update(BASE_HEADERS)
def test_sqlite3_integrity_error(mocker): session = urlquick.Session() mocked = mocker.patch.object(session.cache_adapter, "conn", autospec=True) mocked.execute.side_effect = sqlite3.IntegrityError("file is encrypted") session.cache_adapter.wipe()
def get_live_url(plugin, item_id, **kwargs): # Using script (https://github.com/Catch-up-TV-and-More/plugin.video.catchuptvandmore/issues/484) # Create session session_urlquick = urlquick.Session() json_parser = json.loads(genparams(item_id)) params = json_parser['params'] paramsencoded = urlencode(params) # Get Token # KO - resp = session_urlquick.get(URL_COMPTE_LOGIN) resp = session_urlquick.get(URL_CONNECT_AUTHORIZE, params=params, max_age=-1) value_token = re.compile( r'__RequestVerificationToken\" type\=\"hidden\" value\=\"(.*?)\"' ).findall(resp.text)[0] if plugin.setting.get_string('abweb.login') == '' or \ plugin.setting.get_string('abweb.password') == '': xbmcgui.Dialog().ok( 'Info', plugin.localize(30604) % ('ABWeb', 'http://www.abweb.com/BIS-TV-Online/abonnement.aspx')) return False # Build PAYLOAD payload = { "__RequestVerificationToken": value_token, "Email": plugin.setting.get_string('abweb.login'), "Password": plugin.setting.get_string('abweb.password'), "button": 'login' } paramslogin = { 'ReturnUrl': '/connect/authorize/callback?%s' % paramsencoded } headers = {'Content-Type': 'application/x-www-form-urlencoded'} resp2 = session_urlquick.post(URL_ACCOUNT_LOGIN, params=paramslogin, data=payload, headers=headers, verify=False) next_url = resp2.history[1].headers['location'] code_value = re.compile(r'code\=(.*?)\&').findall(next_url)[0] code_verifier = json_parser['code_verifier'] paramtoken = { 'client_id': item_id, 'code': code_value, 'redirect_uri': URL_AUTH_CALLBACK % item_id, 'code_verifier': code_verifier, 'grant_type': 'authorization_code' } headers = { 'Content-Type': 'application/x-www-form-urlencoded', 'Referer': URL_ROOT % item_id, 'User-Agent': web_utils.get_random_ua() } resp3 = session_urlquick.post(URL_CONNECT_TOKEN, headers=headers, data=paramtoken, max_age=-1) json_parser3 = json.loads(resp3.text) token = json_parser3['id_token'] headers = { 'Accept': 'application/json, text/plain, */*', 'Authorization': 'Bearer %s' % token, 'User-Agent': web_utils.get_random_ua(), 'Referer': URL_AUTH_CALLBACK % item_id } resp4 = session_urlquick.get(URL_API % (item_id, item_id), headers=headers, max_age=-1) json_parser4 = json.loads(resp4.text) is_helper = inputstreamhelper.Helper("mpd") if not is_helper.check_inputstream(): return False item = Listitem() if "hdnts" in json_parser4["hdnts"]: item.path = json_parser4[ "streamBaseUrl"] + "/index.mpd?" + json_parser4["hdnts"] else: item.path = json_parser4[ "streamBaseUrl"] + "/index.mpd?hdnts=" + json_parser4["hdnts"] item.property[INPUTSTREAM_PROP] = 'inputstream.adaptive' item.property['inputstream.adaptive.manifest_type'] = 'mpd' item.property['inputstream.adaptive.license_type'] = 'com.widevine.alpha' item.property['inputstream.adaptive.license_key'] = URL_LICENCE_KEY % ( json_parser4["smToken"], URL_ROOT % item_id, URL_ROOT % item_id) item.label = get_selected_item_label() item.art.update(get_selected_item_art()) item.info.update(get_selected_item_info()) return item
def get_live_url(plugin, item_id, **kwargs): # Using script (https://github.com/Catch-up-TV-and-More/plugin.video.catchuptvandmore/issues/484) # Create session session_urlquick = urlquick.Session() json_parser = json.loads(genparams(item_id)) params = json_parser['params'] paramsencoded = urlencode(params) # Get Token # KO - resp = session_urlquick.get(URL_COMPTE_LOGIN) resp = session_urlquick.get(URL_CONNECT_AUTHORIZE, params=params, max_age=-1) value_token = re.compile( r'__RequestVerificationToken\" type\=\"hidden\" value\=\"(.*?)\"').findall(resp.text)[0] if plugin.setting.get_string('abweb.login') == '' or \ plugin.setting.get_string('abweb.password') == '': xbmcgui.Dialog().ok( 'Info', plugin.localize(30604) % ('ABWeb', 'http://www.abweb.com/BIS-TV-Online/abonnement.aspx')) return False # Build PAYLOAD payload = { "__RequestVerificationToken": value_token, "Email": plugin.setting.get_string('abweb.login'), "Password": plugin.setting.get_string('abweb.password'), "button": 'login' } paramslogin = { 'ReturnUrl': '/connect/authorize/callback?%s' % paramsencoded } headers = { 'Content-Type': 'application/x-www-form-urlencoded' } resp2 = session_urlquick.post(URL_ACCOUNT_LOGIN, params=paramslogin, data=payload, headers=headers, verify=False) next_url = resp2.history[1].headers['location'] code_value = re.compile(r'code\=(.*?)\&').findall(next_url)[0] code_verifier = json_parser['code_verifier'] paramtoken = { 'client_id': item_id, 'code': code_value, 'redirect_uri': URL_AUTH_CALLBACK % item_id, 'code_verifier': code_verifier, 'grant_type': 'authorization_code' } headers = { 'Content-Type': 'application/x-www-form-urlencoded', 'Referer': URL_ROOT % item_id, 'User-Agent': web_utils.get_random_ua() } resp3 = session_urlquick.post(URL_CONNECT_TOKEN, headers=headers, data=paramtoken, max_age=-1) json_parser3 = json.loads(resp3.text) token = json_parser3['id_token'] headers = { 'Accept': 'application/json, text/plain, */*', 'Authorization': 'Bearer %s' % token, 'User-Agent': web_utils.get_random_ua(), 'Referer': URL_AUTH_CALLBACK % item_id } resp4 = session_urlquick.get(URL_API % (item_id, item_id), headers=headers, max_age=-1) json_parser4 = json.loads(resp4.text) return json_parser4['hlsUrl']
import urlquick import requests import shutil import pytest import time @pytest.mark.parametrize("obj", [urlquick, urlquick.Session()]) class TestSessionClean(object): """Clean the database before each and every test.""" # noinspection PyMethodMayBeStatic def setup_method(self): """Remove cache location before each test.""" shutil.rmtree(urlquick.CACHE_LOCATION, ignore_errors=True) def test_get(self, obj, requests_mock): mocked = requests_mock.get('https://www.test.com/test/586', body=b"data") ret = obj.get('https://www.test.com/test/586') assert mocked.called assert ret.from_cache is False assert ret.content == b"data" assert ret.text == "data" def test_options(self, obj, requests_mock): mocked = requests_mock.options('https://www.test.com', json={"test": True}) ret = obj.options('https://www.test.com') assert mocked.called assert ret.from_cache is False