33from __future__ import absolute_import , division , unicode_literals
44
55import os
6- import platform
7- import json
8- import subprocess
9- import shutil
10- from distutils .version import LooseVersion # pylint: disable=import-error,no-name-in-module
11- from datetime import datetime , timedelta
12-
13- try : # Python 3
14- from http .client import BadStatusLine
15- from urllib .error import HTTPError
16- from urllib .request import build_opener , install_opener , ProxyHandler , urlopen
17- except ImportError : # Python 2
18- from httplib import BadStatusLine
19- from urllib2 import build_opener , HTTPError , install_opener , ProxyHandler , urlopen
20-
216from inputstreamhelper import config
227
23- import xbmc
24- from xbmcaddon import Addon
258from xbmcgui import Dialog , DialogProgress
26- import xbmcvfs
279from .kodiutils import execute_jsonrpc , get_addon_info , get_proxies , get_setting , localize , log , set_setting , translate_path
2810from .unicodehelper import to_unicode
2911
@@ -42,9 +24,11 @@ def system_os():
4224
4325 # If it wasn't stored before, get the correct value
4426 if not hasattr (system_os , 'name' ):
45- if xbmc .getCondVisibility ('system.platform.android' ):
27+ from xbmc import getCondVisibility
28+ if getCondVisibility ('system.platform.android' ):
4629 system_os .name = 'Android'
4730 else :
31+ import platform
4832 system_os .name = platform .system ()
4933
5034 # Return the stored value
@@ -64,6 +48,7 @@ def __init__(self, protocol, drm=None):
6448 self .protocol = protocol
6549 self .drm = drm
6650
51+ import platform
6752 log ('Platform information: {platform}' , platform = platform .uname ())
6853
6954 if self .protocol not in config .INPUTSTREAM_PROTOCOLS :
@@ -78,7 +63,13 @@ def __init__(self, protocol, drm=None):
7863 self .drm = config .DRM_SCHEMES [drm ]
7964
8065 # Add proxy support to HTTP requests
81- install_opener (build_opener (ProxyHandler (get_proxies ())))
66+ proxies = get_proxies ()
67+ if proxies :
68+ try : # Python 3
69+ from urllib .request import build_opener , install_opener , ProxyHandler
70+ except ImportError : # Python 2
71+ from urllib2 import build_opener , install_opener , ProxyHandler
72+ install_opener (build_opener (ProxyHandler (proxies )))
8273
8374 def __repr__ (self ):
8475 ''' String representation of Helper class '''
@@ -93,31 +84,36 @@ def _diskspace(cls):
9384 @classmethod
9485 def _temp_path (cls ):
9586 ''' Return temporary path, usually ~/.kodi/userdata/addon_data/script.module.inputstreamhelper/temp '''
87+ from xbmcvfs import exists , mkdirs
9688 temp_path = translate_path (os .path .join (get_setting ('temp_path' , 'special://masterprofile/addon_data/script.module.inputstreamhelper' ), 'temp' ))
97- if not xbmcvfs . exists (temp_path ):
98- xbmcvfs . mkdirs (temp_path )
89+ if not exists (temp_path ):
90+ mkdirs (temp_path )
9991
10092 return temp_path
10193
10294 @classmethod
10395 def _mnt_path (cls ):
10496 ''' Return mount path, usually ~/.kodi/userdata/addon_data/script.module.inputstreamhelper/temp/mnt '''
97+ from xbmcvfs import exists , mkdir
10598 mnt_path = os .path .join (cls ._temp_path (), 'mnt' )
106- if not xbmcvfs . exists (mnt_path ):
107- xbmcvfs . mkdir (mnt_path )
99+ if not exists (mnt_path ):
100+ mkdir (mnt_path )
108101
109102 return mnt_path
110103
111104 @classmethod
112105 def _ia_cdm_path (cls ):
113106 ''' Return the specified CDM path for inputstream.adaptive, usually ~/.kodi/cdm '''
107+ from xbmcaddon import Addon
114108 try :
115109 addon = Addon ('inputstream.adaptive' )
116110 except RuntimeError :
117111 return None
112+
118113 cdm_path = translate_path (addon .getSetting ('DECRYPTERPATH' ))
119- if not xbmcvfs .exists (cdm_path ):
120- xbmcvfs .mkdir (cdm_path )
114+ from xbmcvfs import exists , mkdir
115+ if not exists (cdm_path ):
116+ mkdir (cdm_path )
121117
122118 return cdm_path
123119
@@ -131,6 +127,7 @@ def _widevine_config_path(cls):
131127 @classmethod
132128 def _load_widevine_config (cls ):
133129 ''' Load the widevine or recovery config in JSON format '''
130+ import json
134131 with open (cls ._widevine_config_path (), 'r' ) as config_file :
135132 return json .loads (config_file .read ())
136133
@@ -143,20 +140,23 @@ def _widevine_path(cls):
143140
144141 if cls ._ia_cdm_path ():
145142 widevine_path = os .path .join (cls ._ia_cdm_path (), widevine_cdm_filename )
146- if xbmcvfs .exists (widevine_path ):
143+ from xbmcvfs import exists
144+ if exists (widevine_path ):
147145 return widevine_path
148146
149147 return False
150148
151149 @classmethod
152150 def _kodi_version (cls ):
153151 ''' Return the current Kodi version '''
154- version = xbmc .getInfoLabel ('System.BuildVersion' )
152+ from xbmc import getInfoLabel
153+ version = getInfoLabel ('System.BuildVersion' )
155154 return version .split (' ' )[0 ]
156155
157156 @classmethod
158157 def _arch (cls ):
159158 """Map together and return the system architecture."""
159+ import platform
160160 arch = platform .machine ()
161161 if arch == 'aarch64' :
162162 import struct
@@ -191,6 +191,7 @@ def _sizeof_fmt(num, suffix='B'):
191191 def _cmd_exists (cmd ):
192192 """Check whether cmd exists on system."""
193193 # https://stackoverflow.com/questions/377017/test-if-executable-exists-in-python
194+ import subprocess
194195 return subprocess .call ('type ' + cmd , shell = True , stdout = subprocess .PIPE , stderr = subprocess .PIPE ) == 0
195196
196197 def _update_temp_path (self , new_temp_path ):
@@ -199,6 +200,7 @@ def _update_temp_path(self, new_temp_path):
199200
200201 set_setting ('temp_path' , new_temp_path )
201202 if old_temp_path != self ._temp_path ():
203+ import shutil
202204 shutil .move (old_temp_path , self ._temp_path ())
203205
204206 def _helper_disabled (self ):
@@ -228,6 +230,7 @@ def enable():
228230
229231 def _inputstream_version (self ):
230232 ''' Return the requested inputstream version '''
233+ from xbmcaddon import Addon
231234 try :
232235 addon = Addon (self .inputstream_addon )
233236 except RuntimeError :
@@ -265,6 +268,7 @@ def _chromeos_offset(self, bin_path):
265268
266269 def _run_cmd (self , cmd , sudo = False , shell = False ):
267270 ''' Run subprocess command and return if it succeeds as a bool '''
271+ import subprocess
268272 output = ''
269273 success = False
270274 if sudo and os .getuid () != 0 and self ._cmd_exists ('sudo' ):
@@ -345,6 +349,15 @@ def _has_widevine(self):
345349 @staticmethod
346350 def _http_request (url ):
347351 ''' Perform an HTTP request and return request '''
352+
353+ try : # Python 3
354+ from http .client import BadStatusLine
355+ from urllib .error import HTTPError
356+ from urllib .request import urlopen
357+ except ImportError : # Python 2
358+ from httplib import BadStatusLine
359+ from urllib2 import HTTPError , urlopen
360+
348361 log ('Request URL: {url}' , url = url )
349362 filename = url .split ('/' )[- 1 ]
350363
@@ -448,6 +461,7 @@ def _supports_widevine(self):
448461 Dialog ().ok (localize (30004 ), localize (30011 , os = system_os ())) # Operating system not supported by Widevine
449462 return False
450463
464+ from distutils .version import LooseVersion # pylint: disable=import-error,no-name-in-module
451465 if LooseVersion (config .WIDEVINE_MINIMUM_KODI_VERSION [system_os ()]) > LooseVersion (self ._kodi_version ()):
452466 log ('Unsupported Kodi version for Widevine: {version}' , version = self ._kodi_version ())
453467 Dialog ().ok (localize (30004 ), localize (30010 , version = config .WIDEVINE_MINIMUM_KODI_VERSION [system_os ()])) # Kodi too old
@@ -486,6 +500,7 @@ def _select_best_chromeos_image(devices):
486500 continue
487501
488502 # Select the newest version
503+ from distutils .version import LooseVersion # pylint: disable=import-error,no-name-in-module
489504 if LooseVersion (device ['version' ]) > LooseVersion (best ['version' ]):
490505 log ('{device[hwid]} ({device[version]}) is newer than {best[hwid]} ({best[version]})' , # pylint: disable=invalid-format-index
491506 device = device ,
@@ -511,6 +526,7 @@ def _latest_widevine_version(self, eula=False):
511526 versions = self ._http_get (url )
512527 return versions .split ()[- 1 ]
513528
529+ from datetime import datetime
514530 import time
515531 set_setting ('last_update' , str (time .mktime (datetime .utcnow ().timetuple ())))
516532 if 'x86' in self ._arch ():
@@ -648,6 +664,7 @@ def _install_widevine_arm(self): # pylint: disable=too-many-statements
648664 progress_dialog .update (97 , line1 = localize (30050 )) # Finishing
649665 self ._cleanup ()
650666 if self ._has_widevine ():
667+ import json
651668 set_setting ('chromeos_version' , arm_device ['version' ])
652669 with open (self ._widevine_config_path (), 'w' ) as config_file :
653670 config_file .write (json .dumps (devices , indent = 4 ))
@@ -679,9 +696,10 @@ def install_widevine(self):
679696 def remove_widevine (self ):
680697 """Removes Widevine CDM"""
681698 widevinecdm = self ._widevine_path ()
682- if widevinecdm and xbmcvfs .exists (widevinecdm ):
699+ from xbmcvfs import delete , exists
700+ if widevinecdm and exists (widevinecdm ):
683701 log ('Remove Widevine CDM at {path}' , path = widevinecdm )
684- xbmcvfs . delete (widevinecdm )
702+ delete (widevinecdm )
685703 Dialog ().notification (localize (30037 ), localize (30052 )) # Success! Widevine successfully removed.
686704 return True
687705 Dialog ().notification (localize (30004 ), localize (30053 )) # Error. Widevine CDM not found.
@@ -696,6 +714,7 @@ def _first_run():
696714 addon_version = get_addon_info ('version' )
697715
698716 # Compare versions
717+ from distutils .version import LooseVersion # pylint: disable=import-error,no-name-in-module
699718 if LooseVersion (addon_version ) > LooseVersion (settings_version ):
700719 # New version found, save addon_version to settings
701720 set_setting ('version' , addon_version )
@@ -707,6 +726,7 @@ def _update_widevine(self):
707726 """Prompts user to upgrade Widevine CDM when a newer version is available."""
708727 last_update = get_setting ('last_update' )
709728 if last_update and not self ._first_run ():
729+ from datetime import datetime , timedelta
710730 last_update_dt = datetime .fromtimestamp (float (get_setting ('last_update' )))
711731 if last_update_dt + timedelta (days = int (get_setting ('update_frequency' , '14' ))) >= datetime .utcnow ():
712732 log ('Widevine update check was made on {date}' , date = last_update_dt .isoformat ())
@@ -723,6 +743,7 @@ def _update_widevine(self):
723743 log ('Latest {component} version is {version}' , component = component , version = latest_version )
724744 log ('Current {component} version installed is {version}' , component = component , version = current_version )
725745
746+ from distutils .version import LooseVersion # pylint: disable=import-error,no-name-in-module
726747 if LooseVersion (latest_version ) > LooseVersion (current_version ):
727748 log ('There is an update available for {component}' , component = component )
728749 if Dialog ().yesno (localize (30040 ), localize (30033 ), yeslabel = localize (30034 ), nolabel = localize (30028 )):
@@ -754,6 +775,7 @@ def _widevine_eula(self):
754775
755776 def _extract_widevine_from_img (self ):
756777 ''' Extract the Widevine CDM binary from the mounted Chrome OS image '''
778+ import shutil
757779 for root , dirs , files in os .walk (str (self ._mnt_path ())): # pylint: disable=unused-variable
758780 if str ('libwidevinecdm.so' ) not in files :
759781 continue
@@ -859,6 +881,7 @@ def _unmount(self):
859881
860882 def _cleanup (self ):
861883 ''' Clean up function after Widevine CDM installation '''
884+ import shutil
862885 self ._unmount ()
863886 if self ._attached_loop_dev :
864887 cmd = ['losetup' , '-d' , self ._loop_dev ]
@@ -875,6 +898,7 @@ def _cleanup(self):
875898
876899 def _supports_hls (self ):
877900 """Return if HLS support is available in inputstream.adaptive."""
901+ from distutils .version import LooseVersion # pylint: disable=import-error,no-name-in-module
878902 if LooseVersion (self ._inputstream_version ()) >= LooseVersion (config .HLS_MINIMUM_IA_VERSION ):
879903 return True
880904
@@ -899,9 +923,11 @@ def _check_drm(self):
899923
900924 def _install_inputstream (self ):
901925 """Install inputstream addon."""
926+ from xbmc import executebuiltin
927+ from xbmcaddon import Addon
902928 try :
903929 # See if there's an installed repo that has it
904- xbmc . executebuiltin ('InstallAddon({})' .format (self .inputstream_addon ), wait = True )
930+ executebuiltin ('InstallAddon({})' .format (self .inputstream_addon ), wait = True )
905931
906932 # Check if InputStream add-on exists!
907933 Addon ('{}' .format (self .inputstream_addon ))
@@ -955,6 +981,7 @@ def info_dialog(self):
955981
956982 if system_os () != 'Android' :
957983 text += ' - ' + localize (30820 ) + '\n ' # Widevine information
984+ from datetime import datetime
958985 wv_updated = datetime .fromtimestamp (float (get_setting ('last_update' ))).strftime ("%Y-%m-%d %H:%M" ) if get_setting ('last_update' ) else 'Never'
959986 text += ' - ' + localize (30821 , version = self ._get_lib_version (self ._widevine_path ()), date = wv_updated ) + '\n '
960987 text += ' - ' + localize (30822 , path = self ._ia_cdm_path ()) + '\n '
0 commit comments