@@ -48,6 +48,7 @@ class InputStreamException(Exception):
48
48
49
49
@staticmethod
50
50
def sizeof_fmt (num , suffix = 'B' ):
51
+ """Return size of file in a human readable string."""
51
52
# https://stackoverflow.com/questions/1094841/reusable-library-to-get-human-readable-version-of-file-size
52
53
for unit in ['' , 'Ki' , 'Mi' , 'Gi' , 'Ti' , 'Pi' , 'Ei' , 'Zi' ]:
53
54
if abs (num ) < 1024.0 :
@@ -57,10 +58,12 @@ def sizeof_fmt(num, suffix='B'):
57
58
58
59
@staticmethod
59
60
def _cmd_exists (cmd ):
61
+ """Check whether cmd exists on system."""
60
62
# https://stackoverflow.com/questions/377017/test-if-executable-exists-in-python
61
63
return subprocess .call ('type ' + cmd , shell = True , stdout = subprocess .PIPE , stderr = subprocess .PIPE ) == 0
62
64
63
65
def _arch (self ):
66
+ """Map together and return the system architecture."""
64
67
arch = platform .machine ()
65
68
if arch in config .X86_MAP :
66
69
return config .X86_MAP [arch ]
@@ -71,11 +74,13 @@ def _arch(self):
71
74
return arch
72
75
73
76
def _log (self , string ):
77
+ """InputStream Helper log method."""
74
78
logging_prefix = '[{0}-{1}]' .format (self ._addon .getAddonInfo ('id' ), self ._addon .getAddonInfo ('version' ))
75
79
msg = '{0}: {1}' .format (logging_prefix , string )
76
80
xbmc .log (msg = msg , level = xbmc .LOGDEBUG )
77
81
78
82
def _diskspace (self ):
83
+ """Return the free disk space available (in bytes) in cdm_path."""
79
84
statvfs = os .statvfs (self ._cdm_path ())
80
85
return statvfs .f_frsize * statvfs .f_bavail
81
86
@@ -139,7 +144,7 @@ def _parse_chromeos_offset(self, bin_path):
139
144
140
145
def _run_cmd (self , cmd ):
141
146
try :
142
- output = subprocess .check_output (cmd )
147
+ subprocess .check_output (cmd )
143
148
self ._log ('{0} cmd executed successfully.' .format (cmd ))
144
149
return True
145
150
except subprocess .CalledProcessError , error :
@@ -172,8 +177,6 @@ def _mnt_loop_dev(self):
172
177
cmd .insert (0 , 'sudo' )
173
178
else :
174
179
self ._log ('User refused to give sudo permission.' )
175
- else :
176
- self ._log ('User do not have root permissions and/or sudo installed.' )
177
180
178
181
success = self ._run_cmd (cmd )
179
182
if success :
@@ -183,19 +186,20 @@ def _mnt_loop_dev(self):
183
186
return False
184
187
185
188
def _has_widevine_cdm (self ):
189
+ """Checks if Widevine CDM is installed on system."""
186
190
if xbmc .getCondVisibility ('system.platform.android' ): # widevine is built in on android
187
191
return True
188
192
else :
189
193
for filename in os .listdir (self ._ia_cdm_path ()):
190
194
if 'widevine' in filename and filename .endswith (config .CDM_EXTENSIONS ):
191
- self ._log (
192
- 'Found Widevine binary at {0}' .format (os .path .join (self ._ia_cdm_path (), filename )))
195
+ self ._log ('Found Widevine binary at {0}' .format (os .path .join (self ._ia_cdm_path (), filename )))
193
196
return True
194
197
195
198
self ._log ('Widevine is not installed.' )
196
199
return False
197
200
198
201
def _json_rpc_request (self , payload ):
202
+ """Kodi JSON-RPC request. Return the response in a dictionary."""
199
203
self ._log ('jsonrpc payload: {0}' .format (payload ))
200
204
response = xbmc .executeJSONRPC (json .dumps (payload ))
201
205
self ._log ('jsonrpc response: {0}' .format (response ))
@@ -290,6 +294,7 @@ def _enable_inputstream(self):
290
294
return True
291
295
292
296
def _supports_widevine (self ):
297
+ """Check if Widevine is supported on the architecture/operating system/Kodi version."""
293
298
dialog = xbmcgui .Dialog ()
294
299
if xbmc .getCondVisibility ('system.platform.android' ):
295
300
min_version = config .WIDEVINE_ANDROID_MINIMUM_KODI_VERSION
@@ -339,6 +344,7 @@ def _parse_chromeos_recovery_conf(self):
339
344
return devices
340
345
341
346
def _install_widevine_cdm_x86 (self ):
347
+ """Install Widevine CDM on x86 based architectures."""
342
348
dialog = xbmcgui .Dialog ()
343
349
if dialog .yesno (self ._language (30001 ), self ._language (30002 )):
344
350
cdm_version = self ._current_widevine_cdm_version ()
@@ -369,6 +375,7 @@ def _install_widevine_cdm_x86(self):
369
375
return False
370
376
371
377
def _install_widevine_cdm_arm (self ):
378
+ """Install Widevine CDM on ARM-based architectures."""
372
379
arm_device = [x for x in self ._parse_chromeos_recovery_conf () if config .CHROMEOS_ARM_HWID in x ['hwidmatch' ]][0 ]
373
380
required_diskspace = int (arm_device ['filesize' ]) + int (arm_device ['zipfilesize' ])
374
381
dialog = xbmcgui .Dialog ()
@@ -403,7 +410,7 @@ def _install_widevine_cdm_arm(self):
403
410
self ._cleanup ()
404
411
busy_dialog .close ()
405
412
else :
406
- self ._extract_cdm_from_img ()
413
+ self ._extract_widevine_cdm_from_img ()
407
414
self ._install_cdm ()
408
415
self ._cleanup ()
409
416
if self ._has_widevine_cdm ():
@@ -417,7 +424,7 @@ def _install_widevine_cdm_arm(self):
417
424
return False
418
425
419
426
def _widevine_eula (self ):
420
- """Displays the Widevine EULA."""
427
+ """Display the Widevine EULA and prompt user to accept it ."""
421
428
if os .path .exists (os .path .join (self ._cdm_path (), config .WIDEVINE_LICENSE_FILE )):
422
429
license_file = os .path .join (self ._cdm_path (), config .WIDEVINE_LICENSE_FILE )
423
430
with open (license_file , 'r' ) as f :
@@ -435,7 +442,7 @@ def _widevine_eula(self):
435
442
dialog = xbmcgui .Dialog ()
436
443
return dialog .yesno (self ._language (30026 ), eula , yeslabel = self ._language (30027 ), nolabel = self ._language (30028 ))
437
444
438
- def _extract_cdm_from_img (self ):
445
+ def _extract_widevine_cdm_from_img (self ):
439
446
"""Extract the Widevine CDM binary from the mounted Chrome OS image."""
440
447
for root , dirs , files in os .walk (self ._mnt_path ()):
441
448
for filename in files :
@@ -450,9 +457,10 @@ def _install_cdm(self):
450
457
"""Loop through local cdm folder and symlink/copy binaries to inputstream cdm_path."""
451
458
for cdm_file in os .listdir (self ._cdm_path ()):
452
459
if cdm_file .endswith (config .CDM_EXTENSIONS ):
460
+ self ._log ('[install_cdm] found file: {0}' .format (cdm_file ))
453
461
cdm_path_addon = os .path .join (self ._cdm_path (), cdm_file )
454
462
cdm_path_inputstream = os .path .join (self ._ia_cdm_path (), cdm_file )
455
- if self ._os == 'Windows' : # don't symlink on Windows
463
+ if self ._os == 'Windows' : # copy on windows
456
464
shutil .copyfile (cdm_path_addon , cdm_path_inputstream )
457
465
else :
458
466
os .symlink (cdm_path_addon , cdm_path_inputstream )
@@ -491,11 +499,11 @@ def _cleanup(self):
491
499
return True
492
500
493
501
def _supports_hls (self ):
502
+ """Return if HLS support is available in inputstream.adaptive."""
494
503
if LooseVersion (self ._inputstream_version ()) >= LooseVersion (config .HLS_MINIMUM_IA_VERSION ):
495
504
return True
496
505
else :
497
- self ._log (
498
- 'HLS is not supported on {0} version {1}' .format (self ._inputstream_addon , self ._inputstream_version ()))
506
+ self ._log ('HLS is unsupported on {0} version {1}' .format (self ._inputstream_addon , self ._inputstream_version ()))
499
507
dialog = xbmcgui .Dialog ()
500
508
dialog .ok (self ._language (30004 ),
501
509
self ._language (30017 ).format (self ._inputstream_addon , config .HLS_MINIMUM_IA_VERSION ))
0 commit comments