1
1
import platform , os , sys , stat , tempfile , re , subprocess
2
2
from browserstack .bserrors import BrowserStackLocalError
3
3
import gzip
4
+ import json
4
5
5
6
try :
6
7
from urllib .request import urlopen , Request
10
11
class LocalBinary :
11
12
_version = None
12
13
13
- def __init__ (self ):
14
+ def __init__ (self , key , error_object = None ):
15
+ self .key = key
16
+ self .error_object = error_object
14
17
is_64bits = sys .maxsize > 2 ** 32
15
18
self .is_windows = False
16
19
osname = platform .system ()
17
- source_url = "https://www.browserstack.com/local-testing/downloads/binaries/"
20
+ source_url = self . fetch_source_url () + '/'
18
21
19
22
if osname == 'Darwin' :
20
23
self .http_path = source_url + "BrowserStackLocal-darwin-x64"
@@ -37,6 +40,31 @@ def __init__(self):
37
40
]
38
41
self .path_index = 0
39
42
43
+ def fetch_source_url (self ):
44
+ url = "https://local.browserstack.com/binary/api/v1/endpoint"
45
+ headers = {
46
+ "Content-Type" : "application/json" ,
47
+ "Accept" : "application/json"
48
+ }
49
+ data = {"auth_token" : self .key }
50
+
51
+ if self .error_object is not None :
52
+ data ["error_message" ] = str (self .error_object )
53
+ headers ["X-Local-Fallback-Cloudflare" ] = "true"
54
+
55
+ req = Request (url , data = json .dumps (data ).encode ("utf-8" ))
56
+ for key , value in headers .items ():
57
+ req .add_header (key , value )
58
+
59
+ try :
60
+ with urlopen (req ) as response :
61
+ resp_bytes = response .read ()
62
+ resp_str = resp_bytes .decode ('utf-8' )
63
+ resp_json = json .loads (resp_str )
64
+ return resp_json ["data" ]["endpoint" ]
65
+ except Exception as e :
66
+ raise BrowserStackLocalError ('Error trying to fetch the source url for downloading the binary: {}' .format (e ))
67
+
40
68
@staticmethod
41
69
def set_version (version ):
42
70
LocalBinary ._version = version
@@ -61,7 +89,7 @@ def __available_dir(self):
61
89
return final_path
62
90
else :
63
91
self .path_index += 1
64
- raise BrowserStackLocalError ('Error trying to download BrowserStack Local binary' )
92
+ raise BrowserStackLocalError ('Error trying to download BrowserStack Local binary, exhausted user directories to download to. ' )
65
93
66
94
def download (self , chunk_size = 8192 , progress_hook = None ):
67
95
headers = {
@@ -80,6 +108,7 @@ def download(self, chunk_size=8192, progress_hook=None):
80
108
total_size = int (response .info ().get_all ('Content-Length' )[0 ].strip () or '0' )
81
109
bytes_so_far = 0
82
110
111
+ # Limits retries to the number of directories
83
112
dest_parent_dir = self .__available_dir ()
84
113
dest_binary_name = 'BrowserStackLocal'
85
114
if self .is_windows :
0 commit comments