Skip to content

Commit 5839666

Browse files
committed
Autoinstall Widevine updates
This adds a feature to enable automatic installation of Widevine.
1 parent defc09a commit 5839666

File tree

5 files changed

+121
-68
lines changed

5 files changed

+121
-68
lines changed

.pylintrc

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ disable=
55
import-outside-toplevel,
66
line-too-long,
77
old-style-class,
8+
too-many-arguments,
89
too-many-branches,
910
too-many-lines,
1011
too-many-return-statements,

lib/inputstreamhelper/__init__.py

+67-65
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222

2323
import xbmc
2424
from xbmcaddon import Addon
25-
from xbmcgui import Dialog, DialogProgress
2625
import xbmcvfs
27-
from .kodiutils import execute_jsonrpc, get_addon_info, get_proxies, get_setting, localize, log, set_setting, translate_path
26+
from .kodiutils import (browsesingle, execute_jsonrpc, get_addon_info, get_proxies, get_setting, localize, log,
27+
notification, ok_dialog, progress_dialog, set_setting, textviewer, translate_path, yesno_dialog)
2828
from .unicodehelper import to_unicode
2929

3030
# NOTE: Work around issue caused by platform still using os.popen()
@@ -356,11 +356,11 @@ def _http_request(url):
356356
raise HTTPError('HTTP %s Error for url: %s' % (req.getcode(), url), response=req)
357357
break
358358
except HTTPError:
359-
Dialog().ok(localize(30004), localize(30013, filename=filename)) # Failed to retrieve file
359+
ok_dialog(localize(30004), localize(30013, filename=filename)) # Failed to retrieve file
360360
return None
361361
except BadStatusLine:
362362
if retry:
363-
Dialog().ok(localize(30004), localize(30013, filename=filename)) # Failed to retrieve file
363+
ok_dialog(localize(30004), localize(30013, filename=filename)) # Failed to retrieve file
364364
return None
365365
return req
366366

@@ -387,8 +387,8 @@ def _http_download(self, url, message=None):
387387

388388
self._download_path = os.path.join(self._temp_path(), filename)
389389
total_length = float(req.info().get('content-length'))
390-
progress_dialog = DialogProgress()
391-
progress_dialog.create(localize(30014), message) # Download in progress
390+
progress = progress_dialog()
391+
progress.create(localize(30014), message) # Download in progress
392392

393393
chunk_size = 32 * 1024
394394
with open(self._download_path, 'wb') as image:
@@ -400,13 +400,13 @@ def _http_download(self, url, message=None):
400400
image.write(chunk)
401401
size += len(chunk)
402402
percent = int(size * 100 / total_length)
403-
if progress_dialog.iscanceled():
404-
progress_dialog.close()
403+
if progress.iscanceled():
404+
progress.close()
405405
req.close()
406406
return False
407-
progress_dialog.update(percent)
407+
progress.update(percent)
408408

409-
progress_dialog.close()
409+
progress.close()
410410
return True
411411

412412
def _has_inputstream(self):
@@ -440,22 +440,22 @@ def _supports_widevine(self):
440440
"""Checks if Widevine is supported on the architecture/operating system/Kodi version."""
441441
if self._arch() not in config.WIDEVINE_SUPPORTED_ARCHS:
442442
log('Unsupported Widevine architecture found: {arch}', arch=self._arch())
443-
Dialog().ok(localize(30004), localize(30007)) # Widevine not available on this architecture
443+
ok_dialog(localize(30004), localize(30007)) # Widevine not available on this architecture
444444
return False
445445

446446
if system_os() not in config.WIDEVINE_SUPPORTED_OS:
447447
log('Unsupported Widevine OS found: {os}', os=system_os())
448-
Dialog().ok(localize(30004), localize(30011, os=system_os())) # Operating system not supported by Widevine
448+
ok_dialog(localize(30004), localize(30011, os=system_os())) # Operating system not supported by Widevine
449449
return False
450450

451451
if LooseVersion(config.WIDEVINE_MINIMUM_KODI_VERSION[system_os()]) > LooseVersion(self._kodi_version()):
452452
log('Unsupported Kodi version for Widevine: {version}', version=self._kodi_version())
453-
Dialog().ok(localize(30004), localize(30010, version=config.WIDEVINE_MINIMUM_KODI_VERSION[system_os()])) # Kodi too old
453+
ok_dialog(localize(30004), localize(30010, version=config.WIDEVINE_MINIMUM_KODI_VERSION[system_os()])) # Kodi too old
454454
return False
455455

456456
if 'WindowsApps' in translate_path('special://xbmcbin/'): # uwp is not supported
457457
log('Unsupported UWP Kodi version detected.')
458-
Dialog().ok(localize(30004), localize(30012)) # Windows Store Kodi falls short
458+
ok_dialog(localize(30004), localize(30012)) # Windows Store Kodi falls short
459459
return False
460460

461461
return True
@@ -522,7 +522,7 @@ def _latest_widevine_version(self, eula=False):
522522
arm_device = self._select_best_chromeos_image(devices)
523523
if arm_device is None:
524524
log('We could not find an ARM device in recovery.conf')
525-
Dialog().ok(localize(30004), localize(30005))
525+
ok_dialog(localize(30004), localize(30005))
526526
return ''
527527
return arm_device['version']
528528

@@ -555,12 +555,12 @@ def _install_widevine_x86(self):
555555

556556
downloaded = self._http_download(url)
557557
if downloaded:
558-
progress_dialog = DialogProgress()
559-
progress_dialog.create(heading=localize(30043), line1=localize(30044)) # Extracting Widevine CDM
560-
progress_dialog.update(94, line1=localize(30049)) # Installing Widevine CDM
558+
progress = progress_dialog()
559+
progress.create(heading=localize(30043), line1=localize(30044)) # Extracting Widevine CDM
560+
progress.update(94, line1=localize(30049)) # Installing Widevine CDM
561561
self._unzip(self._ia_cdm_path())
562562

563-
progress_dialog.update(97, line1=localize(30050)) # Finishing
563+
progress.update(97, line1=localize(30050)) # Finishing
564564
self._cleanup()
565565
if not self._widevine_eula():
566566
return False
@@ -571,13 +571,13 @@ def _install_widevine_x86(self):
571571
os.rename(os.path.join(self._ia_cdm_path(), config.WIDEVINE_MANIFEST_FILE), self._widevine_config_path())
572572
wv_check = self._check_widevine()
573573
if wv_check:
574-
progress_dialog.update(100, line1=localize(30051)) # Widevine CDM successfully installed.
575-
Dialog().notification(localize(30037), localize(30051)) # Success! Widevine successfully installed.
576-
progress_dialog.close()
574+
progress.update(100, line1=localize(30051)) # Widevine CDM successfully installed.
575+
notification(localize(30037), localize(30051)) # Success! Widevine successfully installed.
576+
progress.close()
577577
return wv_check
578578

579-
progress_dialog.close()
580-
Dialog().ok(localize(30004), localize(30005)) # An error occurred
579+
progress.close()
580+
ok_dialog(localize(30004), localize(30005)) # An error occurred
581581

582582
return False
583583

@@ -588,52 +588,54 @@ def _install_widevine_arm(self): # pylint: disable=too-many-statements
588588
arm_device = self._select_best_chromeos_image(devices)
589589
if arm_device is None:
590590
log('We could not find an ARM device in recovery.conf')
591-
Dialog().ok(localize(30004), localize(30005))
591+
ok_dialog(localize(30004), localize(30005))
592592
return ''
593593
required_diskspace = int(arm_device['filesize']) + int(arm_device['zipfilesize'])
594-
if Dialog().yesno(localize(30001), # Due to distributing issues, this takes a long time
595-
localize(30006, diskspace=self._sizeof_fmt(required_diskspace))) and self._widevine_eula():
594+
if yesno_dialog(localize(30001), # Due to distributing issues, this takes a long time
595+
localize(30006, diskspace=self._sizeof_fmt(required_diskspace)),
596+
autoanswer=True) and self._widevine_eula():
596597
if system_os() != 'Linux':
597-
Dialog().ok(localize(30004), localize(30019, os=system_os()))
598+
ok_dialog(localize(30004), localize(30019, os=system_os()))
598599
return False
599600

600601
while required_diskspace >= self._diskspace():
601-
if Dialog().yesno(localize(30004), localize(30055)): # Not enough space, alternative path?
602-
self._update_temp_path(Dialog().browseSingle(3, localize(30909), 'files')) # Temporary path
602+
if yesno_dialog(localize(30004), localize(30055)): # Not enough space, alternative path?
603+
self._update_temp_path(browsesingle(3, localize(30909), 'files')) # Temporary path
603604
continue
604605

605-
Dialog().ok(localize(30004), # Not enough free disk space
606-
localize(30018, diskspace=self._sizeof_fmt(required_diskspace)))
606+
ok_dialog(localize(30004), # Not enough free disk space
607+
localize(30018, diskspace=self._sizeof_fmt(required_diskspace)))
607608
return False
608609

609610
if not self._cmd_exists('fdisk') and not self._cmd_exists('parted'):
610-
Dialog().ok(localize(30004), localize(30020, command1='fdisk', command2='parted')) # Commands are missing
611+
ok_dialog(localize(30004), localize(30020, command1='fdisk', command2='parted')) # Commands are missing
611612
return False
612613

613614
if not self._cmd_exists('mount'):
614-
Dialog().ok(localize(30004), localize(30021, command='mount')) # Mount command is missing
615+
ok_dialog(localize(30004), localize(30021, command='mount')) # Mount command is missing
615616
return False
616617

617618
if not self._cmd_exists('losetup'):
618-
Dialog().ok(localize(30004), localize(30021, command='losetup')) # Losetup command is missing
619+
ok_dialog(localize(30004), localize(30021, command='losetup')) # Losetup command is missing
619620
return False
620621

621-
if os.getuid() != 0: # ask for permissions to run cmds as root
622-
if not Dialog().yesno(localize(30001), localize(30030, cmds=', '.join(root_cmds)), yeslabel=localize(30027), nolabel=localize(30028)):
623-
return False
622+
if os.getuid() != 0 and not yesno_dialog(localize(30001), # Ask for permission to run cmds as root
623+
localize(30030, cmds=', '.join(root_cmds)),
624+
nolabel=localize(30028), yeslabel=localize(30027), autoanswer=True):
625+
return False
624626

625627
# Clean up any remaining mounts
626628
self._unmount()
627629

628630
url = arm_device['url']
629631
downloaded = self._http_download(url, message=localize(30022)) # Downloading the recovery image
630632
if downloaded:
631-
progress_dialog = DialogProgress()
632-
progress_dialog.create(heading=localize(30043), line1=localize(30044)) # Extracting Widevine CDM
633+
progress = progress_dialog()
634+
progress.create(heading=localize(30043), line1=localize(30044)) # Extracting Widevine CDM
633635
bin_filename = url.split('/')[-1].replace('.zip', '')
634636
bin_path = os.path.join(self._temp_path(), bin_filename)
635637

636-
progress_dialog.update(5, line1=localize(30045), line2=localize(30046), line3=localize(30047)) # Uncompressing image
638+
progress.update(5, line1=localize(30045), line2=localize(30046), line3=localize(30047)) # Uncompressing image
637639
success = [
638640
self._unzip(self._temp_path(), bin_filename),
639641
self._check_loop(),
@@ -642,27 +644,27 @@ def _install_widevine_arm(self): # pylint: disable=too-many-statements
642644
self._mnt_loop_dev(),
643645
]
644646
if all(success):
645-
progress_dialog.update(91, line1=localize(30048)) # Extracting Widevine CDM
647+
progress.update(91, line1=localize(30048)) # Extracting Widevine CDM
646648
self._extract_widevine_from_img()
647-
progress_dialog.update(94, line1=localize(30049)) # Installing Widevine CDM
648-
progress_dialog.update(97, line1=localize(30050)) # Finishing
649+
progress.update(94, line1=localize(30049)) # Installing Widevine CDM
650+
progress.update(97, line1=localize(30050)) # Finishing
649651
self._cleanup()
650652
if self._has_widevine():
651653
set_setting('chromeos_version', arm_device['version'])
652654
with open(self._widevine_config_path(), 'w') as config_file:
653655
config_file.write(json.dumps(devices, indent=4))
654656
wv_check = self._check_widevine()
655657
if wv_check:
656-
progress_dialog.update(100, line1=localize(30051)) # Widevine CDM successfully installed.
657-
Dialog().notification(localize(30037), localize(30051)) # Success! Widevine CDM successfully installed.
658-
progress_dialog.close()
658+
progress.update(100, line1=localize(30051)) # Widevine CDM successfully installed.
659+
notification(localize(30037), localize(30051)) # Success! Widevine CDM successfully installed.
660+
progress.close()
659661
return wv_check
660662
else:
661-
progress_dialog.update(100, line1=localize(30050)) # Finishing
663+
progress.update(100, line1=localize(30050)) # Finishing
662664
self._cleanup()
663665

664-
progress_dialog.close()
665-
Dialog().ok(localize(30004), localize(30005)) # An error occurred
666+
progress.close()
667+
ok_dialog(localize(30004), localize(30005)) # An error occurred
666668

667669
return False
668670

@@ -682,9 +684,9 @@ def remove_widevine(self):
682684
if widevinecdm and xbmcvfs.exists(widevinecdm):
683685
log('Remove Widevine CDM at {path}', path=widevinecdm)
684686
xbmcvfs.delete(widevinecdm)
685-
Dialog().notification(localize(30037), localize(30052)) # Success! Widevine successfully removed.
687+
notification(localize(30037), localize(30052)) # Success! Widevine successfully removed.
686688
return True
687-
Dialog().notification(localize(30004), localize(30053)) # Error. Widevine CDM not found.
689+
notification(localize(30004), localize(30053)) # Error. Widevine CDM not found.
688690
return False
689691

690692
@staticmethod
@@ -725,7 +727,7 @@ def _update_widevine(self):
725727

726728
if LooseVersion(latest_version) > LooseVersion(current_version):
727729
log('There is an update available for {component}', component=component)
728-
if Dialog().yesno(localize(30040), localize(30033), yeslabel=localize(30034), nolabel=localize(30028)):
730+
if yesno_dialog(localize(30040), localize(30033), nolabel=localize(30028), yeslabel=localize(30034), autoanswer=True):
729731
self.install_widevine()
730732
else:
731733
log('User declined to update {component}.', component=component)
@@ -750,7 +752,7 @@ def _widevine_eula(self):
750752
with archive.open(config.WIDEVINE_LICENSE_FILE) as file_obj:
751753
eula = file_obj.read().decode().strip().replace('\n', ' ')
752754

753-
return Dialog().yesno(localize(30026), eula, yeslabel=localize(30027), nolabel=localize(30028)) # Widevine CDM EULA
755+
return yesno_dialog(localize(30026), eula, nolabel=localize(30028), yeslabel=localize(30027), autoanswer=True) # Widevine CDM EULA
754756

755757
def _extract_widevine_from_img(self):
756758
''' Extract the Widevine CDM binary from the mounted Chrome OS image '''
@@ -799,7 +801,7 @@ def _missing_widevine_libs(self):
799801
import struct
800802
if struct.calcsize('P') * 8 == 64:
801803
log('ARM64 ldd check failed. User needs 32-bit userspace.')
802-
Dialog().ok(localize(30004), localize(30039)) # Widevine not available on ARM64
804+
ok_dialog(localize(30004), localize(30039)) # Widevine not available on ARM64
803805

804806
log('Failed to check for missing Widevine libraries.')
805807
return None
@@ -811,18 +813,18 @@ def _check_widevine(self):
811813

812814
if not os.path.exists(self._widevine_config_path()):
813815
log('Widevine or recovery config is missing. Reinstall is required.')
814-
Dialog().ok(localize(30001), localize(30031)) # An update of Widevine is required
816+
ok_dialog(localize(30001), localize(30031)) # An update of Widevine is required
815817
return self.install_widevine()
816818

817819
if 'x86' in self._arch(): # check that widevine arch matches system arch
818820
wv_config = self._load_widevine_config()
819821
if config.WIDEVINE_ARCH_MAP_X86[self._arch()] != wv_config['arch']:
820822
log('Widevine/system arch mismatch. Reinstall is required.')
821-
Dialog().ok(localize(30001), localize(30031)) # An update of Widevine is required
823+
ok_dialog(localize(30001), localize(30031)) # An update of Widevine is required
822824
return self.install_widevine()
823825

824826
if self._missing_widevine_libs():
825-
Dialog().ok(localize(30004), localize(30032, libs=', '.join(self._missing_widevine_libs()))) # Missing libraries
827+
ok_dialog(localize(30004), localize(30032, libs=', '.join(self._missing_widevine_libs()))) # Missing libraries
826828
return False
827829

828830
self._update_widevine()
@@ -866,7 +868,7 @@ def _cleanup(self):
866868
if unattach_output['success']:
867869
self._loop_dev = False
868870
if self._modprobe_loop:
869-
Dialog().notification(localize(30035), localize(30036)) # Unload by hand in CLI
871+
notification(localize(30035), localize(30036)) # Unload by hand in CLI
870872
if not self._has_widevine():
871873
shutil.rmtree(self._ia_cdm_path())
872874

@@ -892,7 +894,7 @@ def _check_drm(self):
892894
if self._has_widevine():
893895
return self._check_widevine()
894896

895-
if Dialog().yesno(localize(30041), localize(30002), yeslabel=localize(30038), nolabel=localize(30028)): # Widevine required
897+
if yesno_dialog(localize(30041), localize(30002), nolabel=localize(30028), yeslabel=localize(30038), autoanswer=True): # Widevine required
896898
return self.install_widevine()
897899

898900
return False
@@ -921,18 +923,18 @@ def check_inputstream(self):
921923
if not self._has_inputstream():
922924
# Try to install InputStream add-on
923925
if not self._install_inputstream():
924-
Dialog().ok(localize(30004), localize(30008, addon=self.inputstream_addon)) # inputstream is missing on system
926+
ok_dialog(localize(30004), localize(30008, addon=self.inputstream_addon)) # inputstream is missing on system
925927
return False
926928
elif not self._inputstream_enabled():
927-
ret = Dialog().yesno(localize(30001), localize(30009, addon=self.inputstream_addon)) # inputstream is disabled
929+
ret = yesno_dialog(localize(30001), localize(30009, addon=self.inputstream_addon)) # inputstream is disabled
928930
if ret:
929931
self._enable_inputstream()
930932
return False
931933
log('{addon} {version} is installed and enabled.', addon=self.inputstream_addon, version=self._inputstream_version())
932934

933935
if self.protocol == 'hls' and not self._supports_hls():
934-
Dialog().ok(localize(30004), # HLS Minimum version is needed
935-
localize(30017, addon=self.inputstream_addon, version=config.HLS_MINIMUM_IA_VERSION))
936+
ok_dialog(localize(30004), # HLS Minimum version is needed
937+
localize(30017, addon=self.inputstream_addon, version=config.HLS_MINIMUM_IA_VERSION))
936938
return False
937939

938940
return self._check_drm()
@@ -963,4 +965,4 @@ def info_dialog(self):
963965
+ "\n - ".join(wv_info) + "\n\n"
964966
+ localize(30830, url=config.ISSUE_URL))
965967

966-
Dialog().textviewer(localize(30901), text)
968+
textviewer(localize(30901), text)

0 commit comments

Comments
 (0)