def get_kodi_setting(name, total=False): """ Retorna el valor de configuracion del parametro solicitado. Devuelve el valor del parametro 'name' en la configuracion global de Kodi @param default: valor devuelto en caso de que no exista el parametro name @type default: any @return: El valor del parametro 'name' @rtype: any """ # Global Kodi setting #from core import scrapertools try: inpath = os.path.join(translatePath('special://masterprofile/'), "guisettings.xml") infile = open(inpath, "rb") data = infile.read() if not PY3: data = data.encode("utf-8", "ignore") elif PY3 and isinstance(data, (bytes, bytearray)): data = "".join(chr(x) for x in data) infile.close() except: data = '' try: import traceback from platformcode import logger logger.error(traceback.format_exc()) # Verificar si hay problemas de permisos de acceso a userdata from core.filetools import file_info, listdir, dirname logger.error("Error al leer guisettings.xml: %s, ### Folder-info: %s, ### File-info: %s" % \ (inpath, file_info(dirname(inpath)), listdir(dirname(inpath), file_inf=True))) except: pass ret = {} # matches = scrapertools.find_multiple_matches(data, '<setting\s*id="([^"]+)"[^>]*>([^<]*)<\/setting>') matches = re.compile('<setting\s*id="([^"]+)"[^>]*>([^<]*)<\/setting>', re.DOTALL).findall(data) for _id, value in matches: # hack para devolver el tipo correspondiente ret[_id] = get_setting_values(_id, value, decode_var_=False) if _id == name and not total: return ret[_id] if not total: return None else: return ret
def get_environment(): """ Devuelve las variables de entorno del OS, de Kodi y de Alfa más habituales, necesarias para el diagnóstico de fallos """ try: import base64 import ast environment = config.get_platform(full_version=True) environment['num_version'] = str(environment['num_version']) environment['python_version'] = '%s (%s, %s)' % (str(platform.python_version()), \ str(sys.api_version), str(platform.python_implementation())) environment['os_release'] = str(platform.release()) environment['prod_model'] = '' try: import multiprocessing environment['proc_num'] = ' (%sx)' % str( multiprocessing.cpu_count()) except: environment['proc_num'] = '' if xbmc.getCondVisibility("system.platform.Windows"): try: if platform.platform(): environment['os_release'] = str( platform.platform()).replace('Windows-', '') elif platform._syscmd_ver()[2]: environment['os_release'] = str(platform._syscmd_ver()[2]) command = ["wmic", "cpu", "get", "name"] p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, creationflags=0x08000000) output_cmd, error_cmd = p.communicate() if PY3 and isinstance(output_cmd, bytes): output_cmd = output_cmd.decode() output_cmd = re.sub(r'\n|\r|\s{2}', '', output_cmd) environment['prod_model'] = str(scrapertools.find_single_match(output_cmd, \ '\w+.*?(?i)(?:Intel\(R\))?(?:\s*Core\(TM\))\s*(.*?CPU.*?)\s*(?:\@|$)')) except: pass if xbmc.getCondVisibility("system.platform.Android"): environment['os_name'] = 'Android' try: for label_a in subprocess.check_output('getprop').split(FF): if PY3 and isinstance(label_a, bytes): label_a = label_a.decode() if 'build.version.release' in label_a: environment['os_release'] = str( scrapertools.find_single_match( label_a, ':\s*\[(.*?)\]$')) if 'product.model' in label_a: environment['prod_model'] = str( scrapertools.find_single_match( label_a, ':\s*\[(.*?)\]$')) except: try: for label_a in filetools.read(os.environ['ANDROID_ROOT'] + '/build.prop').split(): if 'build.version.release' in label_a: environment['os_release'] = str( scrapertools.find_single_match( label_a, '=(.*?)$')) if 'product.model' in label_a: environment['prod_model'] = str( scrapertools.find_single_match( label_a, '=(.*?)$')) except: pass environment['prod_model'] += ' (%s)' % config.is_rooted( silent=True) elif xbmc.getCondVisibility("system.platform.Linux"): environment['os_name'] = 'Linux' try: for label_a in subprocess.check_output('hostnamectl').split( FF): if PY3 and isinstance(label_a, bytes): label_a = label_a.decode() if 'Operating' in label_a: environment['os_release'] = str( scrapertools.find_single_match( label_a, 'Operating\s*S\w+:\s*(.*?)\s*$')) break for label_a in subprocess.check_output( ['cat', '/proc/cpuinfo']).split(FF): if PY3 and isinstance(label_a, bytes): label_a = label_a.decode() if 'model name' in label_a: environment['prod_model'] = str(scrapertools.find_single_match(label_a, \ 'model.*?:\s*(?i)(?:Intel\(R\))?(?:\s*Core\(TM\))\s*(.*?CPU.*?)\s*(?:\@|$)')) break except: pass elif xbmc.getCondVisibility("system.platform.Linux.RaspberryPi"): environment['os_name'] = 'RaspberryPi' else: environment['os_name'] = str(platform.system()) if not environment['os_release']: environment['os_release'] = str(platform.release()) if environment['proc_num'] and environment['prod_model']: environment['prod_model'] += environment['proc_num'] environment['machine'] = str(platform.machine()) environment['architecture'] = str(sys.maxsize > 2**32 and "64-bit" or "32-bit") environment['language'] = str(xbmc.getInfoLabel('System.Language')) environment['cpu_usage'] = str(xbmc.getInfoLabel('System.CpuUsage')) environment['mem_total'] = str( xbmc.getInfoLabel('System.Memory(total)')).replace('MB', '').replace( 'KB', '') environment['mem_free'] = str( xbmc.getInfoLabel('System.Memory(free)')).replace('MB', '').replace( 'KB', '') if not environment['mem_total'] or not environment['mem_free']: try: if environment['os_name'].lower() == 'windows': kernel32 = ctypes.windll.kernel32 c_ulong = ctypes.c_ulong c_ulonglong = ctypes.c_ulonglong class MEMORYSTATUS(ctypes.Structure): _fields_ = [('dwLength', c_ulong), ('dwMemoryLoad', c_ulong), ('dwTotalPhys', c_ulonglong), ('dwAvailPhys', c_ulonglong), ('dwTotalPageFile', c_ulonglong), ('dwAvailPageFile', c_ulonglong), ('dwTotalVirtual', c_ulonglong), ('dwAvailVirtual', c_ulonglong), ('availExtendedVirtual', c_ulonglong)] memoryStatus = MEMORYSTATUS() memoryStatus.dwLength = ctypes.sizeof(MEMORYSTATUS) kernel32.GlobalMemoryStatus(ctypes.byref(memoryStatus)) environment['mem_total'] = str( old_div(int(memoryStatus.dwTotalPhys), (1024**2))) environment['mem_free'] = str( old_div(int(memoryStatus.dwAvailPhys), (1024**2))) else: with open('/proc/meminfo') as f: meminfo = f.read() environment['mem_total'] = str( old_div( int( re.search(r'MemTotal:\s+(\d+)', meminfo).groups()[0]), 1024)) environment['mem_free'] = str( old_div( int( re.search(r'MemAvailable:\s+(\d+)', meminfo).groups()[0]), 1024)) except: environment['mem_total'] = '' environment['mem_free'] = '' try: environment['kodi_buffer'] = '20' environment['kodi_bmode'] = '0' environment['kodi_rfactor'] = '4.0' if filetools.exists( filetools.join("special://userdata", "advancedsettings.xml")): advancedsettings = filetools.read( filetools.join("special://userdata", "advancedsettings.xml")).split('\n') for label_a in advancedsettings: if 'memorysize' in label_a: environment['kodi_buffer'] = str( old_div( int( scrapertools.find_single_match( label_a, '>(\d+)<\/')), 1024**2)) if 'buffermode' in label_a: environment['kodi_bmode'] = str( scrapertools.find_single_match( label_a, '>(\d+)<\/')) if 'readfactor' in label_a: environment['kodi_rfactor'] = str( scrapertools.find_single_match( label_a, '>(.*?)<\/')) except: pass environment['userdata_path'] = str(config.get_data_path()) environment['userdata_path_perm'] = filetools.file_info( environment['userdata_path']) if not environment['userdata_path_perm']: del environment['userdata_path_perm'] try: if environment['os_name'].lower() == 'windows': free_bytes = ctypes.c_ulonglong(0) ctypes.windll.kernel32.GetDiskFreeSpaceExW( ctypes.c_wchar_p(environment['userdata_path']), None, None, ctypes.pointer(free_bytes)) environment['userdata_free'] = str( round(float(free_bytes.value) / (1024**3), 3)) else: disk_space = os.statvfs(environment['userdata_path']) if not disk_space.f_frsize: disk_space.f_frsize = disk_space.f_frsize.f_bsize environment['userdata_free'] = str(round((float(disk_space.f_bavail) / \ (1024**3)) * float(disk_space.f_frsize), 3)) except: environment['userdata_free'] = '?' if environment['userdata_path_perm']: environment['userdata_path'] = environment['userdata_path_perm'] del environment['userdata_path_perm'] environment['torrent_lang'] = '%s/%s' % (config.get_setting("channel_language", default="").upper(), \ config.get_setting("second_language", default="").upper()) try: environment['videolab_series'] = '?' environment['videolab_episodios'] = '?' environment['videolab_pelis'] = '?' environment['videolab_path'] = str(config.get_videolibrary_path()) environment['videolab_path_perm'] = filetools.file_info( environment['videolab_path']) if not environment['videolab_path_perm']: environment['videolab_path_perm'] = environment[ 'videolab_path'] if filetools.exists(filetools.join(environment['videolab_path'], \ config.get_setting("folder_tvshows"))): environment['videolab_series'] = str(len(filetools.listdir(filetools.join(environment['videolab_path'], \ config.get_setting("folder_tvshows"))))) counter = 0 for root, folders, files in filetools.walk(filetools.join(environment['videolab_path'], \ config.get_setting("folder_tvshows"))): for file in files: if file.endswith('.strm'): counter += 1 environment['videolab_episodios'] = str(counter) if filetools.exists(filetools.join(environment['videolab_path'], \ config.get_setting("folder_movies"))): environment['videolab_pelis'] = str(len(filetools.listdir(filetools.join(environment['videolab_path'], \ config.get_setting("folder_movies"))))) except: pass try: video_updates = [ 'No', 'Inicio', 'Una vez', 'Inicio+Una vez', 'Dos veces al día' ] environment['videolab_update'] = str( video_updates[config.get_setting("update", "videolibrary")]) except: environment['videolab_update'] = '?' try: if environment['os_name'].lower() == 'windows': free_bytes = ctypes.c_ulonglong(0) ctypes.windll.kernel32.GetDiskFreeSpaceExW( ctypes.c_wchar_p(environment['videolab_path']), None, None, ctypes.pointer(free_bytes)) environment['videolab_free'] = str( round(float(free_bytes.value) / (1024**3), 3)) else: disk_space = os.statvfs(environment['videolab_path']) if not disk_space.f_frsize: disk_space.f_frsize = disk_space.f_frsize.f_bsize environment['videolab_free'] = str(round((float(disk_space.f_bavail) / \ (1024**3)) * float(disk_space.f_frsize), 3)) except: environment['videolab_free'] = '?' environment['torrent_list'] = [] environment['torrentcli_option'] = '' environment['torrent_error'] = '' environment['torrentcli_rar'] = config.get_setting("mct_rar_unpack", server="torrent", default=True) environment['torrentcli_backgr'] = config.get_setting( "mct_background_download", server="torrent", default=True) environment['torrentcli_lib_path'] = config.get_setting( "libtorrent_path", server="torrent", default="") if environment['torrentcli_lib_path']: lib_path = 'Activo' else: lib_path = 'Inactivo' if config.get_setting("libtorrent_version", server="torrent", default=""): lib_path += '-%s' % config.get_setting( "libtorrent_version", server="torrent", default="") environment['torrentcli_unrar'] = config.get_setting("unrar_path", server="torrent", default="") if environment['torrentcli_unrar']: if xbmc.getCondVisibility("system.platform.Android"): unrar = 'Android' else: unrar = filetools.dirname(environment['torrentcli_unrar']) unrar = filetools.basename(unrar).capitalize() else: unrar = 'Inactivo' torrent_id = config.get_setting("torrent_client", server="torrent", default=0) environment['torrentcli_option'] = str(torrent_id) torrent_options = platformtools.torrent_client_installed() if lib_path != 'Inactivo': torrent_options = ['MCT'] + torrent_options torrent_options = ['BT'] + torrent_options environment['torrent_list'].append({'Torrent_opt': str(torrent_id), 'Libtorrent': lib_path, \ 'RAR_Auto': str(environment['torrentcli_rar']), \ 'RAR_backgr': str(environment['torrentcli_backgr']), \ 'UnRAR': unrar}) environment['torrent_error'] = config.get_setting("libtorrent_error", server="torrent", default="") if environment['torrent_error']: environment['torrent_list'].append( {'Libtorrent_error': environment['torrent_error']}) for torrent_option in torrent_options: cliente = dict() cliente['D_load_Path'] = '' cliente['Libre'] = '?' cliente['Plug_in'] = torrent_option.replace('Plugin externo: ', '') if cliente['Plug_in'] == 'BT': cliente['D_load_Path'] = str( config.get_setting("bt_download_path", server="torrent", default='')) if not cliente['D_load_Path']: continue cliente['D_load_Path'] = filetools.join( cliente['D_load_Path'], 'BT-torrents') cliente['D_load_Path_perm'] = filetools.file_info( cliente['D_load_Path']) if not cliente['D_load_Path_perm']: del cliente['D_load_Path_perm'] cliente['Buffer'] = str( config.get_setting("bt_buffer", server="torrent", default=50)) elif cliente['Plug_in'] == 'MCT': cliente['D_load_Path'] = str( config.get_setting("mct_download_path", server="torrent", default='')) if not cliente['D_load_Path']: continue cliente['D_load_Path'] = filetools.join( cliente['D_load_Path'], 'MCT-torrent-videos') cliente['D_load_Path_perm'] = filetools.file_info( cliente['D_load_Path']) if not cliente['D_load_Path_perm']: del cliente['D_load_Path_perm'] cliente['Buffer'] = str( config.get_setting("mct_buffer", server="torrent", default=50)) elif xbmc.getCondVisibility('System.HasAddon("plugin.video.%s")' % cliente['Plug_in']): try: __settings__ = xbmcaddon.Addon(id="plugin.video.%s" % cliente['Plug_in']) except: continue cliente['Plug_in'] = cliente['Plug_in'].capitalize() if cliente['Plug_in'] == 'Torrenter': cliente['D_load_Path'] = str( filetools.translatePath( __settings__.getSetting('storage'))) if not cliente['D_load_Path']: cliente['D_load_Path'] = str(filetools.join("special://home/", \ "cache", "xbmcup", "plugin.video.torrenter", "Torrenter")) cliente['D_load_Path_perm'] = filetools.file_info( cliente['D_load_Path']) if not cliente['D_load_Path_perm']: del cliente['D_load_Path_perm'] cliente['Buffer'] = str( __settings__.getSetting('pre_buffer_bytes')) else: cliente['D_load_Path'] = str( filetools.translatePath( __settings__.getSetting('download_path'))) cliente['D_load_Path_perm'] = filetools.file_info( cliente['D_load_Path']) if not cliente['D_load_Path_perm']: del cliente['D_load_Path_perm'] cliente['Buffer'] = str( __settings__.getSetting('buffer_size')) if __settings__.getSetting( 'download_storage' ) == '1' and __settings__.getSetting('memory_size'): cliente['Memoria'] = str( __settings__.getSetting('memory_size')) if cliente['D_load_Path']: try: if environment['os_name'].lower() == 'windows': free_bytes = ctypes.c_ulonglong(0) ctypes.windll.kernel32.GetDiskFreeSpaceExW( ctypes.c_wchar_p(cliente['D_load_Path']), None, None, ctypes.pointer(free_bytes)) cliente['Libre'] = str(round(float(free_bytes.value) / \ (1024**3), 3)).replace('.', ',') else: disk_space = os.statvfs(cliente['D_load_Path']) if not disk_space.f_frsize: disk_space.f_frsize = disk_space.f_frsize.f_bsize cliente['Libre'] = str(round((float(disk_space.f_bavail) / \ (1024**3)) * float(disk_space.f_frsize), 3)).replace('.', ',') except: pass if cliente['D_load_Path_perm']: cliente['D_load_Path'] = cliente['D_load_Path_perm'] del cliente['D_load_Path_perm'] environment['torrent_list'].append(cliente) environment['proxy_active'] = '' try: proxy_channel_bloqued_str = base64.b64decode( config.get_setting('proxy_channel_bloqued')).decode('utf-8') proxy_channel_bloqued = dict() proxy_channel_bloqued = ast.literal_eval(proxy_channel_bloqued_str) for channel_bloqued, proxy_active in list( proxy_channel_bloqued.items()): if proxy_active != 'OFF': environment['proxy_active'] += channel_bloqued + ', ' except: pass if not environment['proxy_active']: environment['proxy_active'] = 'OFF' environment['proxy_active'] = environment['proxy_active'].rstrip(', ') for root, folders, files in filetools.walk("special://logpath/"): for file in files: if file.lower() in ['kodi.log', 'jarvis.log', 'spmc.log', 'cemc.log', \ 'mygica.log', 'wonderbox.log', 'leiapp,log', \ 'leianmc.log', 'kodiapp.log', 'anmc.log', \ 'latin-anmc.log']: environment['log_path'] = str(filetools.join(root, file)) break else: environment['log_path'] = '' break if environment['log_path']: environment['log_size_bytes'] = str( filetools.getsize(environment['log_path'])) environment['log_size'] = str(round(float(environment['log_size_bytes']) / \ (1024*1024), 3)) else: environment['log_size_bytes'] = '' environment['log_size'] = '' environment['debug'] = str(config.get_setting('debug')) environment['addon_version'] = '%s (Upd: %s h.)' % (str(config.get_addon_version()), \ str(config.get_setting("addon_update_timer", default=12)).replace('0', 'No')) environment['assistant_version'] = str(None) if filetools.exists( filetools.join(config.get_data_path(), 'alfa-mobile-assistant.version')): environment['assistant_version'] = filetools.read( filetools.join(config.get_data_path(), 'alfa-mobile-assistant.version')) environment['assistant_cf_ua'] = str( config.get_setting('cf_assistant_ua', None)) except: logger.error(traceback.format_exc()) environment = {} environment['log_size'] = '' environment['cpu_usage'] = '' environment['python_version'] = '' environment['log_path'] = '' environment['userdata_free'] = '' environment['mem_total'] = '' environment['machine'] = '' environment['platform'] = '' environment['videolab_path'] = '' environment['num_version'] = '' environment['os_name'] = '' environment['video_db'] = '' environment['userdata_path'] = '' environment['log_size_bytes'] = '' environment['name_version'] = '' environment['language'] = '' environment['mem_free'] = '' environment['prod_model'] = '' environment['proxy_active'] = '' environment['architecture'] = '' environment['os_release'] = '' environment['videolab_free'] = '' environment['kodi_buffer'] = '' environment['kodi_bmode'] = '' environment['kodi_rfactor'] = '' environment['videolab_series'] = '' environment['videolab_episodios'] = '' environment['videolab_pelis'] = '' environment['videolab_update'] = '' environment['videolab_path_perm'] = '' environment['debug'] = '' environment['addon_version'] = '' environment['torrent_list'] = [] environment['torrent_lang'] = '' environment['torrentcli_option'] = '' environment['torrentcli_rar'] = '' environment['torrentcli_lib_path'] = '' environment['torrentcli_unrar'] = '' environment['torrent_error'] = '' environment['assistant_version'] = '' environment['assistant_cf_ua'] = '' return environment
filetools.join( dest_path, 'liblibtorrent.so')): raise sys.path.insert(0, dest_path) if PY3: ### Alfa try: import libtorrent # Intentamos importar de forma estñandar, por si lo han arreglado except: log(traceback.format_exc(1)) if not libtorrent: dll_path = filetools.join(dest_path, 'liblibtorrent.so') log('CDLL path = ' + str(filetools.file_info(dll_path))) liblibtorrent = CDLL(dll_path) log('CDLL = ' + str(liblibtorrent)) path_list = [dest_path] log('path_list = ' + str(path_list)) fp, pathname, description = imp.find_module( 'libtorrent', path_list) log('fp = ' + str(fp)) log('pathname = ' + str(pathname)) log('description = ' + str(description)) try: libtorrent = imp.load_module('libtorrent', fp, pathname, description) finally: if fp: fp.close()
def get_all_settings_addon(caching_var=True): global alfa_caching, alfa_settings # Si los settings ya están cacheados, se usan. Si no, se cargan por el método tradicional if alfa_caching and caching_var and json.loads(window.getProperty("alfa_settings")): return json.loads(window.getProperty("alfa_settings")).copy() # Lee el archivo settings.xml y retorna un diccionario con {id: value} inpath = os.path.join(get_data_path(), "settings.xml") if not os.path.exists(inpath): # Si no existe el archivo settings.xml, llama a Kodi .setSetting para forzar la creación de un archivo con valores por defecto __settings__.setSetting('caching', 'true') verify_directories_created() if not os.path.exists(inpath): # Comprobamos si Kodi ha generado un archivo settings.xml accesible. Si no es así, se cancela el cacheo y el menú de bienvenida (Apple TV) __settings__.setSetting('show_once', 'true') try: with open(inpath, "rb") as infile: data = infile.read() if not PY3: data = data.encode("utf-8", "ignore") elif PY3 and isinstance(data, (bytes, bytearray)): data = "".join(chr(x) for x in data) except: data = '' alfa_caching = False alfa_settings = {} try: window.setProperty("alfa_caching", '') window.setProperty("alfa_settings", json.dumps(alfa_settings)) import traceback from platformcode import logger logger.error(traceback.format_exc()) # Verificar si hay problemas de permisos de acceso a userdata/alfa from core.filetools import file_info, listdir, dirname logger.error("Error al leer settings.xml: %s, ### Folder-info: %s, ### File-info: %s" % \ (inpath, file_info(dirname(inpath)), listdir(dirname(inpath), file_inf=True))) except: pass ret = {} # matches = scrapertools.find_multiple_matches(data, '<setting\s*id="([^"]*)"\s*value="([^"]*)"') matches = re.compile('<setting\s*id="([^"]*)"\s*value="([^"]*)"', re.DOTALL).findall(data) if not matches: # matches = scrapertools.find_multiple_matches(data, '<setting\s*id="([^"]+)"[^>]*>([^<]*)<\/') matches = re.compile('<setting\s*id="([^"]+)"[^>]*>([^<]*)<\/', re.DOTALL).findall(data) for _id, value in matches: # ret[_id] = get_setting(_id, caching_var=False) ret[_id] = get_setting_values(_id, value, decode_var_=False) alfa_settings = ret.copy() alfa_caching = False if alfa_settings: alfa_caching = alfa_settings.get('caching', True) if alfa_caching: window.setProperty("alfa_caching", str(alfa_caching)) else: window.setProperty("alfa_caching", '') if not alfa_caching: alfa_settings = {} alfa_kodi_platform = {} alfa_channels = {} alfa_servers = {} window.setProperty("alfa_channels", json.dumps(alfa_channels)) window.setProperty("alfa_servers", json.dumps(alfa_servers)) window.setProperty("alfa_settings", json.dumps(alfa_settings)) return ret
def install_alfa_assistant(update=False, remote='', verbose=False): if update: logger.info('update=%s' % str(update)) # Si ya está instalada, devolvemos el control app_name = 'com.alfa.alfamobileassistant' if not verbose: verbose = config.get_setting('addon_update_message') # Verbose en la actualización/instalación assistant_flag_install = config.get_setting('assistant_flag_install', default=True) addonid = 'alfa-mobile-assistant' download = addonid + '.apk' package = addonid + '.apk' version = addonid + '.version' forced_menu = False respuesta = False alfa_s = True addons_path = config.get_runtime_path() if filetools.exists(filetools.join(addons_path, 'channels', 'custom.py')): alfa_s = False if not remote: ANDROID_STORAGE = os.getenv('ANDROID_STORAGE') if not ANDROID_STORAGE: ANDROID_STORAGE = '/storage' else: # Remote es la url de un servidor FTP o SMB activo que apunta a la ruta "/storage" del dispositivo Android ANDROID_STORAGE = remote if ANDROID_STORAGE.endswith('/'): ANDROID_STORAGE = ANDROID_STORAGE[:-1] apk_files = '%s/%s/%s/%s/%s/%s' % (ANDROID_STORAGE, 'emulated', '0', 'Android', 'data', app_name) if ASSISTANT_MODE == 'este' and not filetools.exists(filetools.dirname(apk_files)): apk_files_alt = scrapertools.find_single_match(os.getenv('HOME'), '(.*?)\/\w*.\w*.\w*\/files') logger.info('HOME: ' + apk_files_alt) if apk_files_alt and filetools.exists(apk_files_alt): apk_files = '%s/%s' % (apk_files_alt, app_name) version_path = filetools.join(config.get_data_path(), version) version_act = filetools.read(version_path, silent=True) if not version_act: version_act = '0.0.0' # Averiguamos si es instalacción, update, o forzado desde el Menú de Ajustes if not update and ASSISTANT_MODE == 'este' and filetools.exists(apk_files): return version_act, app_name if ASSISTANT_MODE == 'este' and not update: check_permissions_alfa_assistant() # activamos la app por si no se ha inicializado time.sleep(1) if filetools.exists(apk_files): return version_act, app_name # Mirarmos si la app está activa y obtenemos el nº de versión version_dict = get_generic_call('getWebViewInfo', timeout=2-EXTRA_TIMEOUT, alfa_s=True) if isinstance(version_dict, dict): version_app = version_dict.get('assistantVersion', '') try: android_version = int(scrapertools.find_single_match(version_dict.get('userAgent', ''), r"Android\s*(\d+)")) except: android_version = 8 else: version_app = version_dict android_version = 8 if version_app and not update: return version_app, app_name if version_app: app_active = True else: app_active = False if ASSISTANT_MODE == "este": execute_in_alfa_assistant_with_cmd('open') # activamos la app por si no se ha inicializado time.sleep(5) version_dict = get_generic_call('getWebViewInfo', timeout=2-EXTRA_TIMEOUT, alfa_s=True) if isinstance(version_dict, dict): version_app = version_dict.get('assistantVersion', '') try: android_version = int(scrapertools.find_single_match(version_dict.get('userAgent', ''), r"Android\s*(\d+)")) except: android_version = 8 else: version_app = version_dict android_version = 8 version_actual = filetools.read(version_path, silent=True) if not version_actual and version_app: version_actual = version_app filetools.write(version_path, version_actual, mode='wb', silent=True) elif not version_actual: version_actual = '0.0.0' if ASSISTANT_MODE != 'este': if not version_app: if verbose or (update and not isinstance(update, bool)): platformtools.dialog_notification("Active Alfa Assistant", "o Instale manualmente desde [COLOR yellow]https://bit.ly/2Zwpfzq[/COLOR]") logger.info("Active Alfa Assistant, o Instale manualmente desde [COLOR yellow]https://bit.ly/2Zwpfzq[/COLOR]", force=True) config.set_setting('assistant_flag_install', False) return version_app, app_name else: config.set_setting('assistant_flag_install', True) if not update: return version_app, app_name elif not update and not assistant_flag_install and not filetools.exists(apk_files): logger.info('NO está instalada. El usuario no quiere instalaciñon automática: %s' % app_name) return False, app_name elif update and isinstance(update, bool) and not filetools.exists(apk_files): logger.info('NO está instalada. No se va a actualizar: %s' % app_name) return False, app_name elif update and not isinstance(update, bool) and not filetools.exists(apk_files): logger.info('NO está instalada. Viene del Menú y se va a instalar: %s' % app_name) update = False forced_menu = True elif not remote and not xbmc.getCondVisibility("system.platform.android"): logger.info('El sistema local no es Android: %s' % app_name) return False, app_name logger.info('assistant_mode=%s, update=%s, forced_menu=%s, assistant_flag_install=%s, version_actual=%s, version_app=%s, android=%s, app_active=%s' \ % (ASSISTANT_MODE, str(update), str(forced_menu), str(assistant_flag_install), version_actual, \ version_app, str(android_version), str(app_active))) # Si no está instalada, o se quiere actualizar, empezamos el proceso alfa_assistant_pwd = '' assistant_urls = ['https://github.com/alfa-addon/alfa-repo/raw/master/downloads/assistant/%s' % version, \ 'https://bitbucket.org/alfa_addon/alfa-repo/raw/master/downloads/assistant/%s' % version] apk_updated = filetools.join(addons_path, 'tools') apk_path = filetools.join(apk_updated, download) apk_apk = filetools.join(apk_updated, package) upk_install_path = filetools.join('special://xbmc/', 'files').replace('/cache/apk/assets', '') if not remote: apk_install = filetools.join(ANDROID_STORAGE, 'emulated', '0', 'Download') apk_install_SD = filetools.join(apk_install, package) else: apk_install = '%s/%s/%s/%s' % (ANDROID_STORAGE, 'emulated', '0', 'Download') apk_install_SD = '%s/%s' % (apk_install, package) if not update and not remote and not forced_menu: # Probamos a iniciar por si se ha instalado manualmente y no se ha iniciado la estrucutra de archivos check_permissions_alfa_assistant() try: command = ['pm', 'list', 'packages'] p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) PM_LIST, error_cmd = p.communicate() if PY3 and isinstance(label_a, bytes): PM_LIST = PM_LIST.decode() if app_name in PM_LIST: logger.info('Ya instalada. Volvemos: %s' % app_name) return version_actual, app_name except: logger.error(traceback.format_exc(1)) if not update and not forced_menu and not platformtools.dialog_yesno("Instalación Alfa Assistant", \ "¿Desea instalar la App [COLOR yellow][B]%s[/B][/COLOR]\n" % app_name + " como ayuda para acceder a ciertos canales y servidores?"): config.set_setting('assistant_flag_install', False) return respuesta, app_name elif update and not isinstance(update, bool): platformtools.dialog_notification("Instalación Alfa Assistant", "Comienza la actualización") elif forced_menu: platformtools.dialog_notification("Instalación Alfa Assistant", "Comienza la instalación") # Comprobamos si el dispositivo está rooteado is_rooted = config.is_rooted(silent=True) # ¡OJO! puede pedir permisos root en algunos dispositivos if is_rooted == 'rooted' and ASSISTANT_MODE == 'este': # El dispositivo esta rooteado? update_install = 'py' # Se actualiza desde esta función else: update_install = 'app' # Se actualiza desde la app cmd = 'update' # Comando de la app para auto actualizarse dataURI = 'Version:%s' # Versión a actualizar # Comprobamos si hay acceso a Github o BitBucket for assistant_rar in assistant_urls: response = httptools.downloadpage(assistant_rar, timeout=5, ignore_response_code=True, alfa_s=alfa_s, json_to_utf8=False) if response.sucess: break # Descargamos el archivo de version. Si hay error avisamos, pero continuamos if not response.sucess: if update and isinstance(update, bool): logger.error("Error en la descarga de control de versión. No se puede actualizar: %s" % str(response.code)) return respuesta, app_name platformtools.dialog_notification("Instalación Alfa Assistant", "Error en la descarga de control de versión. Seguimos") logger.error("Error en la descarga de control de versión. Seguimos...: %s" % str(response.code)) #Si es una actualización programada, comprobamos las versiones de Github y de lo instalado if update and isinstance(update, bool): if version_actual != response.data: if version_app: version_actual = version_app filetools.write(version_path, version_actual, mode='wb', silent=True) if version_actual == response.data: if verbose: platformtools.dialog_notification("Instalación Alfa Assistant", "Ya está actualizado a version %s" % response.data) logger.info("Alfa Assistant ya actualizado a versión: %s" % response.data) if not app_active and ASSISTANT_MODE == "este": execute_in_alfa_assistant_with_cmd('quit') # desactivamos la app si no estaba iniciada return version_actual, app_name # Guardamos archivo de versión if remote: version_path = '%s/%s/%s/%s/%s/%s/%s/%s/%s/%s/%s/%s' % (ANDROID_STORAGE, 'emulated', '0', 'Android', 'data', 'org.xbmc.kodi', 'files', '.kodi', 'addons', 'plugin.video.alfa', 'tools', version) if not filetools.exists(filetools.dirname(version_path)): logger.error("Ruta a carpeta remota de versión no es estándar: %s" % version_path) version_path = '' version_old = version_actual version_actual = response.data if version_path: res = filetools.write(version_path, response.data, mode='wb', silent=True) if not res: if not update: platformtools.dialog_notification("Instalación Alfa Assistant", \ "Error en la escritura de control de versión. Seguimos...") logger.error("Error en la escritura de control de versión. Seguimos...: %s" % assistant_rar) # Descargamos y guardamos el .APK assistant_rar = assistant_rar.replace(version, download) # Sustituir en la url la versión por el apk res = False if not update: platformtools.dialog_notification("Instalación Alfa Assistant", "Descargando APK") logger.info('Descargando de_ %s' % assistant_rar) response = httptools.downloadpage(assistant_rar, timeout=5, ignore_response_code=True, alfa_s=alfa_s, json_to_utf8=False) if not response.sucess: if not update or verbose: platformtools.dialog_notification("Instalación Alfa Assistant", "Error en la descarga del .apk") response.data = '' logger.error("Error en la descarga del .apk: %s" % str(response.code)) else: # Guardamos archivo descargado de APK res = filetools.write(apk_path, response.data, mode='wb', silent=True) if not res: if not update or verbose: platformtools.dialog_notification("Instalación Alfa Assistant", "Error en la escritura del APK") logger.error("Error en la escritura del APK: %s" % apk_path) else: if '.rar' in download: # Empezando la extracción del .rar del APK try: import rarfile archive = rarfile.RarFile(apk_path) if alfa_assistant_pwd: archive.setpassword(alfa_assistant_pwd) archive.extractall(apk_updated) except: logger.error(traceback.format_exc(1)) elif '.zip' in download: # Empezando la extracción del .rar del APK try: import ziptools archive = ziptools.ziptools() #if alfa_assistant_pwd: archive.setpassword(alfa_assistant_pwd) # No hay password en .zip archive.extract(filetools.basename(apk_updated), filetools.dirname(apk_updated)) except: xbmc.executebuiltin('Extract("%s","%s")' % (filetools.basename(apk_updated), filetools.dirname(apk_updated))) time.sleep(1) # Verificado si está el APK, y si está y es LOCAL lo instalamos if ASSISTANT_MODE == "este": res = filetools.copy(apk_apk, apk_install_SD, silent=True) if not res or not filetools.exists(apk_install_SD): if not update or verbose: platformtools.dialog_notification("Instalación Alfa Assistant", "Error de Extracción o Copia %s" % package) logger.error("Error de Extracción o copia %s" % package) # Si está rooteado se instala/actualiza directamente elif update_install == 'py' and res and filetools.exists(apk_install_SD): # Instalamos: nueva o actualización. if not update: platformtools.dialog_notification("Instalación Alfa Assistant", "Installando %s" % package) logger.info("Installing %s" % package) # Instalación Remota if remote: filetools.remove(apk_apk, silent=True) platformtools.dialog_notification("Alfa Assistant: Descarga Remota terminada", "Instale manualmente desde: %s" % apk_install_SD) logger.info("Alfa Assistant: Descarga Remota terminada. Instale manualmente desde: %s" % apk_install_SD) return version_actual, app_name # Instalación Local if not filetools.exists(upk_install_path): filetools.mkdir(upk_install_path) upk_install_path = filetools.join(upk_install_path, package) res = filetools.copy(apk_install_SD, upk_install_path, ch_mod='777') # Copiamos APK a la partición del Sistema, y cambiamos permisos if not res: if not update or verbose: platformtools.dialog_notification("Instalación Alfa Assistant", "Error de Copia %s" % package) logger.error(str(filetools.listdir(apk_install))) logger.error(filetools.file_info(filetools.dirname(upk_install_path))) logger.error(str(filetools.listdir(filetools.dirname(upk_install_path), file_inf=True))) else: # Intenta la instalación vía ROOT y si no funciona como NO ROOT # Marcamos la opción de instalación, -r si es actualización, -g (todos los permisos granted) si es instalación if filetools.exists(apk_files): pm_opt = '-r' else: pm_opt = '-g' # Listamos todas las opciones de comandos, según las variantes de Android command_list = [ ['adb', 'install', '%s' % upk_install_path], ['su', '-c', 'pm install %s %s' % (pm_opt, upk_install_path)], ['su', '-c', 'pm', 'install', pm_opt, '%s' % upk_install_path], ['su', '-0', 'pm install %s %s' % (pm_opt, upk_install_path)], ['su', '-0', 'pm', 'install', pm_opt, '%s' % upk_install_path] ] for command in command_list: try: logger.info(command, force=True) p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output_cmd, error_cmd = p.communicate() if error_cmd: if error_cmd.startswith('su:'): continue if update: ver_upd = get_generic_call('ping', timeout=2-EXTRA_TIMEOUT, alfa_s=True) if not ver_upd: execute_in_alfa_assistant_with_cmd('open') # activamos la app por si no se ha inicializado time.sleep(5) ver_upd = get_generic_call('ping', timeout=2-EXTRA_TIMEOUT, alfa_s=True) execute_in_alfa_assistant_with_cmd('quit') if ver_upd == version_actual: logger.debug(str(error_cmd), force=True) error_cmd = '' else: check_permissions_alfa_assistant() time.sleep(1) if filetools.exists(apk_files): logger.debug(str(error_cmd), force=True) error_cmd = '' if error_cmd: logger.error(str(error_cmd)) else: respuesta = version_actual break else: respuesta = version_actual break except Exception as e: if not PY3: e = unicode(str(e), "utf8", errors="replace").encode("utf8") logger.error('Command ERROR: %s, %s' % (str(command), str(e))) continue # Ùltimo resorte: instalación manual desde GitHub o actualización desde la app if not respuesta and update: # Si hay que actualizar se verifica el vehículo de instalación logger.info("Instalación Alfa Assistant. Actualización desde la app de %s a %s" % (version_old, version_actual)) version_mod = version_actual if not isinstance(update, bool): version_mod = '9.9.999' # Intenta forzar la actualización si viene desde el Menú if ASSISTANT_MODE == "este": if android_version >= 10: app_active = False respuesta = execute_in_alfa_assistant_with_cmd(cmd, dataURI=dataURI % version_mod) else: if not app_active: execute_in_alfa_assistant_with_cmd('openAndQuit') # activamos la app por si no se ha inicializado time.sleep(5) app_active = False respuesta = get_generic_call(cmd, version=version_mod, alfa_s=alfa_s) else: if app_active: respuesta = get_generic_call(cmd, version=version_mod, alfa_s=alfa_s) if not respuesta and ASSISTANT_MODE != "este": if verbose or not isinstance(update, bool): platformtools.dialog_notification("Instalación Alfa Assistant", "Intente la actualización manualmente %s" % version_actual) logger.info("Instalación Alfa Assistant. Intente la actualización manualmente %s" % version_actual) return False, app_name elif not respuesta: # Update local #respuesta = execute_in_alfa_assistant_with_cmd(cmd, dataURI=dataURI % version_mod) if not respuesta: if verbose or not isinstance(update, bool): platformtools.dialog_notification("Instalación Alfa Assistant", "Actualización en error %s. REINTENTANDO" % version_actual) logger.info("Instalación Alfa Assistant. Actualización en error %s. REINTENTANDO" % version_actual) else: respuesta = version_actual if not respuesta: config.set_setting('assistant_flag_install', False) # No vuelve a intentar la instalación try: #xbmc.executebuiltin('StartAndroidActivity("","android.intent.action.VIEW","application/vnd.android.package-archive","file:%s")' % apk_install_SD) if ASSISTANT_MODE == "este": from lib import generictools assistant_rar = assistant_rar.replace('/raw/', '/tree/') # Apuntar a la web de descargas browser, res = generictools.call_browser(assistant_rar, lookup=True) if browser: filetools.remove(apk_install_SD, silent=True) platformtools.dialog_ok("Alfa Assistant: Instale desde [COLOR yellow]%s[/COLOR]" % browser.capitalize(), "O Instale manualmente desde: [COLOR yellow]%s[/COLOR]" % apk_install_SD) logger.info('Browser: %s, Ruta: %s' % (browser.capitalize(), apk_install_SD)) time.sleep(5) browser, res = generictools.call_browser(assistant_rar, dataType='application/vnd.android.package-archive') filetools.remove(apk_path, silent=True) filetools.remove(upk_install_path, silent=True) else: logger.error('Error de Instalación: NO Browser, Ruta: %s' % apk_install_SD) raise else: logger.error('Error de Instalación: no se puede instalar en remoto: %s' % ASSISTANT_SERVER) raise except: if ASSISTANT_MODE == "este": platformtools.dialog_ok("Alfa Assistant: Error", "Instale manualmente desde: [COLOR yellow]%s[/COLOR]" % apk_install_SD) logger.error("Alfa Assistant: Error. Instale manualmente desde: [COLOR yellow]%s[/COLOR]" % apk_install_SD) filetools.remove(apk_path, silent=True) filetools.remove(upk_install_path, silent=True) else: platformtools.dialog_ok("Alfa Assistant: Error", "Copie a Android manualmente desde: [COLOR yellow]%s[/COLOR]" % apk_apk) logger.error("Alfa Assistant: Error. Copie a Android manualmente desde: [COLOR yellow]%s[/COLOR]" % apk_apk) logger.error(traceback.format_exc(1)) if respuesta: if update: if verbose or not isinstance(update, bool): platformtools.dialog_notification("Alfa Assistant", \ "Actualización con exito: %s" % respuesta) logger.info("Actualización terminada con éxito: %s" % respuesta) else: platformtools.dialog_notification("Alfa Assistant", "Instalación con exito: %s" % respuesta) logger.info("Instalación terminada con éxito: %s" % respuesta) filetools.remove(apk_path, silent=True) filetools.remove(apk_install_SD, silent=True) filetools.remove(upk_install_path, silent=True) if not update and not forced_menu: time.sleep(1) check_permissions_alfa_assistant() time.sleep(1) if app_active and ASSISTANT_MODE == "este": execute_in_alfa_assistant_with_cmd('open') # re-activamos la app para dejarla como estaba return respuesta, app_name
def set_channel_setting(name, value, channel): from . import filetools """ Fija el valor de configuracion del parametro indicado. Establece 'value' como el valor del parametro 'name' en la configuracion propia del canal 'channel'. Devuelve el valor cambiado o None si la asignacion no se ha podido completar. Si se especifica el nombre del canal busca en la ruta \addon_data\plugin.video.alfa\settings_channels el archivo channel_data.json y establece el parametro 'name' al valor indicado por 'value'. Si el parametro 'name' no existe lo añade, con su valor, al archivo correspondiente. @param name: nombre del parametro @type name: str @param value: valor del parametro @type value: str @param channel: nombre del canal @type channel: str @return: 'value' en caso de que se haya podido fijar el valor y None en caso contrario @rtype: str, None """ # Creamos la carpeta si no existe if not filetools.exists( filetools.join(config.get_data_path(), "settings_channels")): filetools.mkdir( filetools.join(config.get_data_path(), "settings_channels")) file_settings = filetools.join(config.get_data_path(), "settings_channels", channel + "_data.json") dict_settings = {} dict_file = None if filetools.exists(file_settings): # Obtenemos configuracion guardada de ../settings/channel_data.json try: dict_file = jsontools.load(filetools.read(file_settings)) dict_settings = dict_file.get('settings', {}) except EnvironmentError: logger.error("ERROR al leer el archivo: %s, parámetro: %s" % (file_settings, name)) logger.error(filetools.file_info(file_settings)) dict_settings[name] = value # comprobamos si existe dict_file y es un diccionario, sino lo creamos if dict_file is None or not dict_file: dict_file = {} dict_file['settings'] = dict_settings # Creamos el archivo ../settings/channel_data.json json_data = jsontools.dump(dict_file) if not filetools.write(file_settings, json_data, silent=True): logger.error("ERROR al salvar el parámetro: %s en el archivo: %s" % (name, file_settings)) logger.error(filetools.file_info(file_settings)) return None return value
def get_channel_setting(name, channel, default=None): from . import filetools """ Retorna el valor de configuracion del parametro solicitado. Devuelve el valor del parametro 'name' en la configuracion propia del canal 'channel'. Busca en la ruta \addon_data\plugin.video.alfa\settings_channels el archivo channel_data.json y lee el valor del parametro 'name'. Si el archivo channel_data.json no existe busca en la carpeta channels el archivo channel.json y crea un archivo channel_data.json antes de retornar el valor solicitado. Si el parametro 'name' tampoco existe en el el archivo channel.json se devuelve el parametro default. @param name: nombre del parametro @type name: str @param channel: nombre del canal @type channel: str @param default: valor devuelto en caso de que no exista el parametro name @type default: any @return: El valor del parametro 'name' @rtype: any """ file_settings = filetools.join(config.get_data_path(), "settings_channels", channel + "_data.json") dict_settings = {} dict_file = {} if filetools.exists(file_settings): # Obtenemos configuracion guardada de ../settings/channel_data.json try: dict_file = jsontools.load(filetools.read(file_settings)) if isinstance(dict_file, dict) and 'settings' in dict_file: dict_settings = dict_file['settings'] except EnvironmentError: logger.error("ERROR al leer el archivo: %s, parámetro: %s" % (file_settings, name)) logger.error(filetools.file_info(file_settings)) if not dict_settings or name not in dict_settings: # Obtenemos controles del archivo ../channels/channel.json try: list_controls, default_settings = get_channel_controls_settings( channel) except: default_settings = {} if name in default_settings: # Si el parametro existe en el channel.json creamos el channel_data.json default_settings.update(dict_settings) dict_settings = default_settings dict_file['settings'] = dict_settings # Creamos el archivo ../settings/channel_data.json json_data = jsontools.dump(dict_file) if not filetools.write(file_settings, json_data, silent=True): logger.error( "ERROR al salvar el parámetro: %s en el archivo: %s" % (name, file_settings)) logger.error(filetools.file_info(file_settings)) # Devolvemos el valor del parametro local 'name' si existe, si no se devuelve default return dict_settings.get(name, default)