Esempio n. 1
0
def gen_sx_autoloader_sd_files():
    retrieve_xci_paths()
    gamelist = get_gamelist(file=sd_xci_cache)
    SD_folder = os.path.join(sx_autoloader_db, 'sd')
    if not os.path.exists(sx_autoloader_db):
        os.makedirs(sx_autoloader_db)
    if not os.path.exists(SD_folder):
        os.makedirs(SD_folder)
    for f in os.listdir(SD_folder):
        fp = os.path.join(SD_folder, f)
        try:
            shutil.rmtree(fp)
        except OSError:
            os.remove(fp)
    print('  * Genereting autoloader files')
    for g in gamelist:
        fileid, fileversion, cctag, nG, nU, nD, baseid = listmanager.parsetags(
            g)
        tfile = os.path.join(SD_folder, fileid)
        new_path = g.replace('\\1: External SD Card\\', 'sdmc:/')
        new_path = new_path.replace('\\', '/')
        with open(tfile, 'w') as text_file:
            text_file.write(new_path)
    print('  * Pushing autoloader files')
    destiny = "1: External SD Card\\sxos\\titles\\00FF0012656180FF\\cach\\sd"
    process = subprocess.Popen([
        nscb_mtp, "TransferFolder", "-ori", SD_folder, "-dst", destiny, "-fbf",
        "true"
    ])
    while process.poll() == None:
        if process.poll() != None:
            process.terminate()
Esempio n. 2
0
def delete_archived():
    retrieve_installed()
    installed = get_gamelist()
    registered = retrieve_registered()
    for game in installed:
        fileid, fileversion, cctag, nG, nU, nD, baseid = listmanager.parsetags(
            game)
        try:
            del registered[fileid]
        except:
            pass
    games = []
    # Name [version][title]
    for k in registered.keys():
        games.append(
            f"{(registered[k])[2]} [{(registered[k])[0]}][{(registered[k])[1]}]"
        )
    print("  * Entering File Picker")
    if not games:
        sys.exit("There isn't any archived games or placeholder on the device")
    title = 'Select registries to delete: \n + Press space or right to select entries \n + Press E to finish selection \n + Press A to select all entries'
    options = games
    picker = Picker(options, title, multi_select=True, min_selection_count=1)

    def end_selection(picker):
        return False, -1

    def select_all(picker):
        return "ALL", -1

    picker.register_custom_handler(ord('e'), end_selection)
    picker.register_custom_handler(ord('E'), end_selection)
    picker.register_custom_handler(ord('a'), select_all)
    picker.register_custom_handler(ord('A'), select_all)
    selected = picker.start()
    if selected[0] == False:
        print("    User didn't select any files")
        return False
    print("  * Starting uninstalling process...")
    arch2delete = []
    if selected[0] == "ALL":
        for k in registered:
            g0 = (registered[k])[2]
            arch2delete.append(g0)
    else:
        for game in selected:
            g = game[0]
            g0 = [pos for pos, char in enumerate(g) if char == '[']
            g0 = (g[0:g0[0]]).strip()
            arch2delete.append(g0)
    counter = len(arch2delete)
    for file in arch2delete:
        process = subprocess.Popen([nscb_mtp, "DeleteRegistry", "-ID", file])
        while process.poll() == None:
            if process.poll() != None:
                process.terminate()
        counter -= 1
        print('...................................................')
        print('STILL ' + str(counter) + ' FILES TO PROCESS')
        print('...................................................')
def gen_sx_autoloader_files(folder, type='hdd', push=False, no_colide=False):
    gamelist = folder_to_list(folder, ['xci', 'xc0'])
    if type == 'hdd':
        SD_folder = os.path.join(sx_autoloader_db, 'hdd')
    else:
        SD_folder = os.path.join(sx_autoloader_db, 'sd')
    if not os.path.exists(sx_autoloader_db):
        os.makedirs(sx_autoloader_db)
    if not os.path.exists(SD_folder):
        os.makedirs(SD_folder)
    for f in os.listdir(SD_folder):
        fp = os.path.join(SD_folder, f)
        try:
            shutil.rmtree(fp)
        except OSError:
            os.remove(fp)
    print('  * Generating autoloader files')
    try:
        for g in gamelist:
            try:
                fileid, fileversion, cctag, nG, nU, nD, baseid = parsetags(g)
                if fileid == 'unknown':
                    continue
                tfile = os.path.join(SD_folder, fileid)
                fileparts = Path(g).parts
                if type == 'hdd':
                    new_path = g.replace(fileparts[0], '"usbhdd:/')
                else:
                    new_path = g.replace(fileparts[0], '"sdmc:/')
                new_path = new_path.replace('\\', '/')
                with open(tfile, 'w') as text_file:
                    text_file.write(new_path)
            except:
                pass
        print('    DONE')
        if push == True:
            if not is_switch_connected():
                sys.exit(
                    "Can't push files. Switch device isn't connected.\nCheck if mtp responder is running!!!"
                )
            print('  * Pushing autoloader files')
            if type == 'hdd':
                destiny = "1: External SD Card\\sxos\\titles\\00FF0012656180FF\\cach\\hdd"
            else:
                destiny = "1: External SD Card\\sxos\\titles\\00FF0012656180FF\\cach\\sd"
            process = subprocess.Popen([
                nscb_mtp, "TransferFolder", "-ori", SD_folder, "-dst", destiny,
                "-fbf", "true"
            ])
            while process.poll() == None:
                if process.poll() != None:
                    process.terminate()
        if no_colide == True:
            cleanup_sx_autoloader_files()
    except BaseException as e:
        Print.error('Exception: ' + str(e))
        pass
Esempio n. 4
0
def parsedinstalled():
	installed={}	
	if os.path.exists(games_installed_cache):	
		gamelist=listmanager.read_lines_to_list(games_installed_cache,all=True)	
		for g in gamelist:
			entry=listmanager.parsetags(g)
			entry=list(entry)		
			entry.append(g)
			installed[entry[0]]=entry
	return installed
def cleanup_sx_autoloader_files():
    from mtp_game_manager import retrieve_xci_paths
    from mtp_game_manager import get_gamelist
    try:
        for f in os.listdir(cachefolder):
            fp = os.path.join(cachefolder, f)
            try:
                shutil.rmtree(fp)
            except OSError:
                os.remove(fp)
    except:
        pass
    if not is_switch_connected():
        sys.exit(
            "Can't push files. Switch device isn't connected.\nCheck if mtp responder is running!!!"
        )
    retrieve_xci_paths()
    print("  * Retriving autoloader files in device. Please Wait...")
    process = subprocess.Popen([
        nscb_mtp, "Retrieve_autoloader_files", "-tfile",
        autoloader_files_cache, "-show", "false"
    ],
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
    while process.poll() == None:
        if process.poll() != None:
            process.terminate()
    if os.path.exists(autoloader_files_cache):
        print("    Success")
    else:
        sys.exit("Autoloader files weren't retrieved properly")
    gamelist = get_gamelist(file=sd_xci_cache)
    autoloader_list = get_gamelist(file=autoloader_files_cache)
    sd_xci_ids = []
    for g in gamelist:
        try:
            fileid, fileversion, cctag, nG, nU, nD, baseid = parsetags(g)
            sd_xci_ids.append(fileid)
        except:
            pass
    files_to_remove = []
    for f in autoloader_list:
        fileparts = Path(f).parts
        if 'sdd' in fileparts and not (fileparts[-1] in sd_xci_ids):
            files_to_remove.append(f)
        elif 'hdd' in fileparts and (fileparts[-1] in sd_xci_ids):
            files_to_remove.append(f)
    print("  * The following files will be removed")
    for f in files_to_remove:
        print("    - " + f)
    for f in files_to_remove:
        process = subprocess.Popen([nscb_mtp, "DeleteFile", "-fp", f])
        while process.poll() == None:
            if process.poll() != None:
                process.terminate()
Esempio n. 6
0
def loop_install(tfile,destiny="SD",verification=True,outfolder=None,ch_medium=True,check_fw=True,patch_keygen=False,ch_base=False,ch_other=False,install_mode="spec1",st_crypto=False,checked=False):
	check_connection()		
	if not os.path.exists(tfile):
		sys.exit(f"Couldn't find {tfile}")		
	if ch_base==True or ch_other==True:
		if checked==False:		
			print("Content check activated")			
			retrieve_installed()
			installed=parsedinstalled()
		elif checked==True:	
			print("Content check activated. Games are preparsed")		
			installed=parsedinstalled()	
	file_list=listmanager.read_lines_to_list(tfile,all=True)
	for item in file_list:
		try:
			if ch_base==True or ch_other==True:
				fileid,fileversion,cctag,nG,nU,nD,baseid=listmanager.parsetags(item)
				if fileid.endswith('000') and fileversion==0 and fileid in installed.keys() and ch_base==True:
					print("Base game already installed. Skipping...")
					listmanager.striplines(tfile,counter=True)
					continue
				elif fileid.endswith('000') and fileid in installed.keys() and ch_other==True:
					updid=fileid[:-3]+'800'
					if fileversion>((installed[fileid])[2]):
						print("Asking DBI to delete previous content")
						process=subprocess.Popen([nscb_mtp,"DeleteID","-ID",fileid])	
						while process.poll()==None:
							if process.poll()!=None:
								process.terminate();					
						process=subprocess.Popen([nscb_mtp,"DeleteID","-ID",updid])		
						while process.poll()==None:
							if process.poll()!=None:
								process.terminate();					
					else:
						print("The update is a previous version than the installed on device.Skipping..")
						listmanager.striplines(tfile,counter=True)
						continue				
				elif ch_other==True	and fileid in installed.keys():
					if fileversion>((installed[fileid])[2]):
						print("Asking DBI to delete previous update")
						process=subprocess.Popen([nscb_mtp,"DeleteID","-ID",fileid])					
						while process.poll()==None:
							if process.poll()!=None:
								process.terminate();
					else:
						print("The update is a previous version than the installed on device.Skipping..")
						listmanager.striplines(tfile,counter=True)
						continue	
		except:pass				
		install(filepath=item,destiny=destiny,verification=verification,outfolder=outfolder,ch_medium=ch_medium,check_fw=check_fw,patch_keygen=patch_keygen,install_mode=install_mode,st_crypto=st_crypto)
		print("")
		listmanager.striplines(tfile,counter=True)
Esempio n. 7
0
def parsedinstalled(exclude_xci=True):
    installed = {}
    if os.path.exists(games_installed_cache):
        gamelist = listmanager.read_lines_to_list(games_installed_cache,
                                                  all=True)
        for g in gamelist:
            if exclude_xci == True:
                if g.endswith('xci') or g.endswith('xc0'):
                    continue
            entry = listmanager.parsetags(g)
            entry = list(entry)
            entry.append(g)
            installed[entry[0]] = entry
    return installed
Esempio n. 8
0
def update_console(libraries="all",
                   destiny="SD",
                   exclude_xci=True,
                   prioritize_nsz=True,
                   tfile=None,
                   verification=True,
                   ch_medium=True,
                   ch_other=False,
                   autoupd_aut=True):
    if tfile == None:
        tfile = os.path.join(NSCB_dir, 'MTP1.txt')
    if os.path.exists(tfile):
        try:
            os.remove(tfile)
        except:
            pass
    libdict = get_libs("source")
    pths = {}
    if libraries == "all":
        for entry in libdict.keys():
            pths[entry] = ((libdict[entry])[0])
    else:
        for entry in libdict.keys():
            if (libdict[entry])[1] == True:
                pths[entry] = ((libdict[entry])[0])
    if not os.path.exists(cachefolder):
        os.makedirs(cachefolder)
    for f in os.listdir(cachefolder):
        fp = os.path.join(cachefolder, f)
        try:
            shutil.rmtree(fp)
        except OSError:
            os.remove(fp)
    print("1. Parsing games in device. Please Wait...")
    process = subprocess.Popen([
        nscb_mtp, "ShowInstalled", "-tfile", games_installed_cache, "-show",
        "false"
    ],
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
    while process.poll() == None:
        if process.poll() != None:
            process.terminate()
    if os.path.exists(games_installed_cache):
        print("   Success")
    gamelist = listmanager.read_lines_to_list(games_installed_cache, all=True)
    installed = {}
    for g in gamelist:
        if exclude_xci == True:
            if g.endswith('xci') or g.endswith('xc0'):
                continue
        entry = listmanager.parsetags(g)
        entry = list(entry)
        entry.append(g)
        installed[entry[0]] = entry
    print("2. Parsing local libraries. Please Wait...")
    locallist = []
    for p in pths.keys():
        locallist += listmanager.folder_to_list(pths[p], ['nsp', 'nsz'])
        print(f'   Parsed Library: "{str(p).upper()}"')
    if prioritize_nsz == True:
        locallist = sorted(locallist, key=lambda x: x[-1])
        locallist.reverse()
    localgames = {}
    for g in locallist:
        entry = listmanager.parsetags(g)
        entry = list(entry)
        entry.append(g)
        if not entry[0] in localgames:
            localgames[entry[0]] = entry
        else:
            v = (localgames[entry[0]])[1]
            if int(entry[1]) > int(v):
                localgames[entry[0]] = entry
    print("3. Searching new updates. Please Wait...")
    gamestosend = {}
    for g in installed.keys():
        if g.endswith('000') or g.endswith('800'):
            try:
                updid = g[:-3] + '800'
                if updid in localgames:
                    if updid in installed:
                        if ((installed[updid])[1]) < ((localgames[updid])[1]):
                            if not updid in gamestosend:
                                gamestosend[updid] = localgames[updid]
                            else:
                                if ((gamestosend[updid])[1]) < (
                                    (localgames[updid])[1]):
                                    gamestosend[updid] = localgames[updid]
                    else:
                        if not updid in gamestosend:
                            gamestosend[updid] = localgames[updid]
                        else:
                            if ((gamestosend[updid])[1]) < (
                                (localgames[updid])[1]):
                                gamestosend[updid] = localgames[updid]
            except:
                pass
        else:
            try:
                if g in localgames:
                    if ((installed[g])[1]) < ((localgames[g])[1]):
                        if not g in gamestosend:
                            gamestosend[g] = localgames[g]
                        else:
                            if ((gamestosend[g])[1]) < ((localgames[g])[1]):
                                gamestosend[g] = localgames[g]
            except:
                pass
    print("4. Searching new dlcs. Please Wait...")
    for g in installed.keys():
        try:
            if g.endswith('000') or g.endswith('800'):
                baseid = g[:-3] + '000'
            else:
                baseid = (installed[g])[6]
            for k in localgames.keys():
                try:
                    if not (k.endswith('000')
                            or k.endswith('800')) and not k in installed:
                        test = get_dlc_baseid(k)
                        if baseid == test:
                            if not k in gamestosend:
                                gamestosend[k] = localgames[k]
                            else:
                                if ((gamestosend[k])[1]) < (
                                    (localgames[k])[1]):
                                    gamestosend[k] = localgames[k]
                except BaseException as e:
                    # Print.error('Exception: ' + str(e))
                    pass
        except BaseException as e:
            # Print.error('Exception: ' + str(e))
            pass
    print("5. List of content that will get installed...")
    gamepaths = []
    if len(gamestosend.keys()) > 0:
        if autoupd_aut == True:
            for i in sorted(gamestosend.keys()):
                fileid, fileversion, cctag, nG, nU, nD, baseid, path = gamestosend[
                    i]
                bname = os.path.basename(path)
                gamepaths.append(path)
                g0 = [pos for pos, char in enumerate(bname) if char == '[']
                g0 = (bname[0:g0[0]]).strip()
                print(
                    f"   * {g0} [{fileid}][{fileversion}] [{cctag}] - {(bname[-3:]).upper()}"
                )
        else:
            options = []
            for i in sorted(gamestosend.keys()):
                fileid, fileversion, cctag, nG, nU, nD, baseid, path = gamestosend[
                    i]
                bname = os.path.basename(path)
                gamepaths.append(path)
                g0 = [pos for pos, char in enumerate(bname) if char == '[']
                g0 = (bname[0:g0[0]]).strip()
                cstring = f"{g0} [{fileid}][{fileversion}] [{cctag}] - {(bname[-3:]).upper()}"
                options.append(cstring)
            if options:
                title = 'Select content to install: \n + Press space or right to select entries \n + Press E to finish selection \n + Press A to select all entries'
                picker = Picker(options,
                                title,
                                multi_select=True,
                                min_selection_count=1)

                def end_selection(picker):
                    return False, -1

                def select_all(picker):
                    return "ALL", -1

                picker.register_custom_handler(ord('e'), end_selection)
                picker.register_custom_handler(ord('E'), end_selection)
                picker.register_custom_handler(ord('a'), select_all)
                picker.register_custom_handler(ord('A'), select_all)
                selected = picker.start()
                if selected[0] == False:
                    print("    User didn't select any files")
                    return False
                if selected[0] == "ALL":
                    pass
                else:
                    newgpaths = []
                    for game in selected:
                        g = game[1]
                        g0 = gamepaths[g]
                        newgpaths.append(g0)
                    gamepaths = newgpaths
        print("6. Generating text file...")
        with open(tfile, 'w', encoding='utf8') as textfile:
            for i in gamepaths:
                textfile.write((i).strip() + "\n")
        print("7. Triggering installer on loop mode.")
        print(
            "   Note:If you interrupt the list use normal install mode to continue list"
        )
        loop_install(tfile,
                     destiny=destiny,
                     verification=verification,
                     ch_medium=ch_medium,
                     ch_other=ch_other,
                     checked=True)
    else:
        print("\n   --- DEVICE IS UP TO DATE ---")
Esempio n. 9
0
def get_archived_info(search_new=True, excludehb=True):
    forecombo = Style.BRIGHT + Back.GREEN + Fore.WHITE
    if not os.path.exists(cachefolder):
        os.makedirs(cachefolder)
    for f in os.listdir(cachefolder):
        fp = os.path.join(cachefolder, f)
        try:
            shutil.rmtree(fp)
        except OSError:
            os.remove(fp)
    print("1. Retrieving registered...")
    dbicsv = os.path.join(cachefolder, "registered.csv")
    process = subprocess.Popen([
        nscb_mtp, "Download", "-ori",
        "4: Installed games\\InstalledApplications.csv", "-dst", dbicsv
    ],
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
    while process.poll() == None:
        if process.poll() != None:
            process.terminate()
    if os.path.exists(dbicsv):
        print("   Success")
    print("2. Checking Installed...")
    process = subprocess.Popen([
        nscb_mtp, "ShowInstalled", "-tfile", games_installed_cache, "-show",
        "false"
    ],
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
    while process.poll() == None:
        if process.poll() != None:
            process.terminate()
    if os.path.exists(games_installed_cache):
        print("   Success")
    gamelist = listmanager.read_lines_to_list(games_installed_cache, all=True)
    dbi_dict = {}
    with open(dbicsv, 'rt', encoding='utf8') as csvfile:
        readCSV = csv.reader(csvfile, delimiter=',')
        id = 0
        ver = 1
        tname = 2
        for row in readCSV:
            try:
                tid = (str(row[id]).upper())[2:]
                version = int(row[ver])
                name = str(row[tname])
                dbi_dict[tid] = [tid, version, name]
            except:
                pass
    installed = {}
    for g in gamelist:
        entry = listmanager.parsetags(g)
        installed[entry[0]] = entry
    print("..........................................................")
    print("ARCHIVED|REGISTERED GAMES")
    print("..........................................................")
    for g in dbi_dict.keys():
        if not g in installed.keys():
            tid, version, name = dbi_dict[g]
            if len(name) > 33:
                name = name[0:30] + '...'
            print(f"{name} [{tid}][{version}]")
    if search_new == True:
        import nutdb
        nutdb.check_other_file(urlconfig, 'versions_txt')
        f = 'nutdb_' + 'versions' + '.txt'
        DATABASE_folder = nutdb.get_DBfolder()
        _dbfile_ = os.path.join(DATABASE_folder, f)
        versiondict = {}
        with open(_dbfile_, 'rt', encoding='utf8') as csvfile:
            readCSV = csv.reader(csvfile, delimiter='|')
            i = 0
            for row in readCSV:
                if i == 0:
                    csvheader = row
                    i = 1
                    if 'id' and 'version' in csvheader:
                        id = csvheader.index('id')
                        ver = csvheader.index('version')
                    else:
                        break
                else:
                    try:
                        tid = str(row[id]).upper()
                        version = str(row[ver]).upper()
                        if tid.endswith('800'):
                            baseid = tid[:-3] + '000'
                        if baseid in versiondict.keys():
                            v = versiondict[baseid]
                            if v < int(version):
                                versiondict[baseid] = int(version)
                        else:
                            versiondict[tid] = int(version)
                    except:
                        pass
        print("..........................................................")
        print("NEW UPDATES")
        print("..........................................................")
        for k in dbi_dict.keys():
            fileid, fileversion, g0 = dbi_dict[k]
            if len(g0) > 33:
                g0 = g0[0:30] + '...'
            else:
                g0 = g0 + (33 - len(g0)) * ' '
            v = 0
            updateid = fileid[:-3] + '800'
            if updateid in dbi_dict.keys() and fileid.endswith('000'):
                continue
            if fileid.endswith('800'):
                try:
                    v = versiondict[baseid]
                except:
                    pass
            else:
                try:
                    v = versiondict[fileid]
                except:
                    pass
            if int(v) > int(fileversion):
                if fileid.endswith('000') or fileid.endswith('800'):
                    updid = fileid[:-3] + '800'
                    print(f"{g0} [{baseid}][{fileversion}] -> " + forecombo +
                          f"[{updid}] [v{v}]" + Style.RESET_ALL)
                else:
                    print(f"{g0} [{fileid}][{fileversion}] -> " + forecombo +
                          f"[{fileid}] [v{v}]" + Style.RESET_ALL)
        print("..........................................................")
        print("NEW DLCS")
        print("..........................................................")
        for k in versiondict.keys():
            if k in dbi_dict.keys() or k.endswith('000') or k.endswith('800'):
                continue
            else:
                baseid = get_dlc_baseid(k)
                updid = baseid[:-3] + '800'
                if baseid in dbi_dict.keys() or updid in dbi_dict.keys():
                    fileid, fileversion, g0 = dbi_dict[baseid]
                    if len(g0) > 33:
                        g0 = g0[0:30] + '...'
                    else:
                        g0 = g0 + ((33 - len(g0)) * ' ')
                    print(f"{g0} [{baseid}] -> " + forecombo +
                          f"[{k}] [v{versiondict[k]}]" + Style.RESET_ALL)
Esempio n. 10
0
def get_installed_info(tfile=None, search_new=True, excludehb=True):
    if not os.path.exists(cachefolder):
        os.makedirs(cachefolder)
    forecombo = Style.BRIGHT + Back.GREEN + Fore.WHITE
    if tfile == "":
        tfile = None
    if os.path.exists(games_installed_cache):
        try:
            os.remove(games_installed_cache)
        except:
            pass
    if tfile == None:
        for f in os.listdir(cachefolder):
            fp = os.path.join(cachefolder, f)
            try:
                shutil.rmtree(fp)
            except OSError:
                os.remove(fp)
        process = subprocess.Popen([
            nscb_mtp, "ShowInstalled", "-tfile", games_installed_cache,
            "-show", "false"
        ],
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
        print("Parsing games in device. Please Wait...")
        while process.poll() == None:
            if process.poll() != None:
                process.terminate()
    if os.path.exists(games_installed_cache):
        gamelist = listmanager.read_lines_to_list(games_installed_cache,
                                                  all=True)
        gamelist.sort()
        print("..........................................................")
        print("CONTENT FOUND ON DEVICE")
        print("..........................................................")
        installed = {}
        for g in gamelist:
            fileid, fileversion, cctag, nG, nU, nD, baseid = listmanager.parsetags(
                g)
            g0 = [pos for pos, char in enumerate(g) if char == '[']
            g0 = (g[0:g0[0]]).strip()
            installed[fileid] = [
                fileid, fileversion, cctag, nG, nU, nD, baseid, g0, g
            ]
            if len(g0) > 33:
                g0 = g0[0:30] + '...'
            else:
                g0 = g0 + ((33 - len(g0)) * ' ')
            verprint = str(fileversion)
            if len(verprint) < 9:
                verprint = verprint + ((9 - len(verprint)) * ' ')
            if excludehb == True:
                if not fileid.startswith('05') and not fileid.startswith(
                        '04') and not str(fileid).lower() == 'unknown':
                    if g.endswith('.xci') or g.endswith('.xc0'):
                        print(
                            f"{g0}|{fileid}|{verprint}|XCI|{nG}G|{nU}U|{nD}D")
                    else:
                        print(f"{g0}|{fileid}|{verprint}|{cctag}")
            else:
                if g.endswith('.xci') or g.endswith('.xc0'):
                    print(f"{g0}|{fileid}|{verprint}|XCI|{nG}G|{nU}U|{nD}D")
                else:
                    print(f"{g0}|{fileid}|{verprint}|{cctag}")
        if search_new == True:
            import nutdb
            nutdb.check_other_file(urlconfig, 'versions_txt')
            f = 'nutdb_' + 'versions' + '.txt'
            DATABASE_folder = nutdb.get_DBfolder()
            _dbfile_ = os.path.join(DATABASE_folder, f)
            versiondict = {}
            with open(_dbfile_, 'rt', encoding='utf8') as csvfile:
                readCSV = csv.reader(csvfile, delimiter='|')
                i = 0
                for row in readCSV:
                    if i == 0:
                        csvheader = row
                        i = 1
                        if 'id' and 'version' in csvheader:
                            id = csvheader.index('id')
                            ver = csvheader.index('version')
                        else:
                            break
                    else:
                        try:
                            tid = str(row[id]).upper()
                            version = str(row[ver]).upper()
                            if tid.endswith('800'):
                                baseid = tid[:-3] + '000'
                            if baseid in versiondict.keys():
                                v = versiondict[baseid]
                                if v < int(version):
                                    versiondict[baseid] = int(version)
                            else:
                                versiondict[tid] = int(version)
                        except:
                            pass
            print("..........................................................")
            print("NEW UPDATES")
            print("..........................................................")
            for k in installed.keys():
                fileid, fileversion, cctag, nG, nU, nD, baseid, g0, g = installed[
                    k]
                if len(g0) > 33:
                    g0 = g0[0:30] + '...'
                else:
                    g0 = g0 + ((33 - len(g0)) * ' ')
                verprint = str(fileversion)
                fillver = ''
                if len(verprint) < 6:
                    fillver = (6 - len(verprint)) * ' '
                v = 0
                updateid = fileid[:-3] + '800'
                if updateid in installed.keys() and fileid.endswith('000'):
                    continue
                if fileid.endswith('800'):
                    try:
                        v = versiondict[baseid]
                    except:
                        pass
                else:
                    try:
                        v = versiondict[fileid]
                    except:
                        pass
                if int(v) > int(fileversion):
                    if fileid.endswith('000') or fileid.endswith('800'):
                        updid = fileid[:-3] + '800'
                        print(f"{g0} [{baseid}][{verprint}]{fillver} -> " +
                              forecombo + f"[{updid}] [v{v}]" +
                              Style.RESET_ALL)
                    else:
                        print(f"{g0} [{fileid}][{verprint}]{fillver} -> " +
                              forecombo + f"[{fileid}] [v{v}]" +
                              Style.RESET_ALL)
            check_xcis = False
            xci_dlcs = {}
            print("..........................................................")
            print("NEW DLCS")
            print("..........................................................")
            for k in versiondict.keys():
                if k in installed.keys() or k.endswith('000') or k.endswith(
                        '800'):
                    continue
                else:
                    baseid = get_dlc_baseid(k)
                    updid = baseid[:-3] + '800'
                    if baseid in installed.keys() or updid in installed.keys():
                        fileid, fileversion, cctag, nG, nU, nD, baseid, g0, g = installed[
                            baseid]
                        if nD > 0:
                            if check_xcis == False:
                                check_xcis = True
                            if not baseid in xci_dlcs.keys():
                                entry = list()
                                entry.append(k)
                                xci_dlcs[baseid] = entry
                            else:
                                entry = xci_dlcs[baseid]
                                entry.append(k)
                                xci_dlcs[baseid] = entry
                            continue
                        if len(g0) > 33:
                            g0 = g0[0:30] + '...'
                        else:
                            g0 = g0 + ((33 - len(g0)) * ' ')
                        print(f"{g0} [{baseid}] -> " + forecombo +
                              f"[{k}] [v{versiondict[k]}]" + Style.RESET_ALL)
            t = 0
            if check_xcis == True:
                for bid in xci_dlcs.keys():
                    fileid, fileversion, cctag, nG, nU, nD, baseid, g0, g = installed[
                        bid]
                    entry = xci_dlcs[bid]
                    test = len(entry)
                    if test > nD:
                        if t == 0:
                            print(
                                ".........................................................."
                            )
                            print("XCI MAY HAVE NEW DLCS. LISTING AVAILABLE")
                            print(
                                ".........................................................."
                            )
                            t += 1
                        if len(g0) > 33:
                            g0 = g0[0:30] + '...'
                        else:
                            g0 = g0 + ((33 - len(g0)) * ' ')
                        for k in xci_dlcs[baseid]:
                            print(f"{g0} [{baseid}] -> " + forecombo +
                                  f"[{k}] [v{versiondict[k]}]" +
                                  Style.RESET_ALL)
def update_console_from_gd(libraries="all",destiny="SD",exclude_xci=True,prioritize_nsz=True,tfile=None,verification=True,ch_medium=True,ch_other=False,autoupd_aut=True,use_archived=False):	
	check_connection()
	if use_archived==True:
		autoupd_aut=False	
	if tfile==None:
		tfile=os.path.join(NSCB_dir, 'MTP1.txt')
	if os.path.exists(tfile):
		try:
			os.remove(tfile)
		except: pass			
	libdict=get_libs_remote_source(remote_lib_file);
	if libdict==False:
		sys.exit("No libraries set up")
	pths={};TDs={};
	if libraries=="all":
		for entry in libdict.keys():
			pths[entry]=((libdict[entry])[0])
			TDs[entry]=((libdict[entry])[1])
	else:
		for entry in libdict.keys():
			if (libdict[entry])[2]==True:
				pths[entry]=((libdict[entry])[0])	
				TDs[entry]=((libdict[entry])[1])
	# print(pths);print(TDs);
	if not os.path.exists(cachefolder):
		os.makedirs(cachefolder)				
	for f in os.listdir(cachefolder):
		fp = os.path.join(cachefolder, f)
		try:
			shutil.rmtree(fp)
		except OSError:
			os.remove(fp)	
	if use_archived!=True:				
		print("1. Parsing games in device. Please Wait...")			
		if exclude_xci==True:
			process=subprocess.Popen([nscb_mtp,"ShowInstalled","-tfile",games_installed_cache,"-show","false","-exci","true"],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
		else:	
			process=subprocess.Popen([nscb_mtp,"ShowInstalled","-tfile",games_installed_cache,"-show","false","-exci","false","-xci_lc",xci_locations],stdout=subprocess.PIPE,stderr=subprocess.PIPE)	
		while process.poll()==None:
			if process.poll()!=None:
				process.terminate();	
		if os.path.exists(games_installed_cache):	
			print("   Success")
		gamelist=listmanager.read_lines_to_list(games_installed_cache,all=True)
		installed={}		
		for g in gamelist:
			try:
				if exclude_xci==True:
					if g.endswith('xci') or g.endswith('xc0'):
						continue
				entry=listmanager.parsetags(g)
				entry=list(entry)		
				entry.append(g)
				installed[entry[0]]=entry	
			except:pass	
		# for i in pths:
			# print(i)
	else:
		print("1. Retrieving registered...")			
		dbicsv=os.path.join(cachefolder,"registered.csv")
		process=subprocess.Popen([nscb_mtp,"Download","-ori","4: Installed games\\InstalledApplications.csv","-dst",dbicsv],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
		while process.poll()==None:
			if process.poll()!=None:
				process.terminate();
		if os.path.exists(dbicsv):	
			print("   Success")					
			installed={}
			with open(dbicsv,'rt',encoding='utf8') as csvfile:
				readCSV = csv.reader(csvfile, delimiter=',')
				id=0;ver=1;tname=2;
				for row in readCSV:		
					try:
						tid=(str(row[id]).upper())[2:]
						version=int(row[ver])
						if version>0 and tid.endswith('000'):
							tid=tid[:-3]+'800'						
						name=str(row[tname])
						g=f"{name} [{tid}][v{version}].nsp"
						entry=listmanager.parsetags(g)
						entry=list(entry)		
						entry.append(g)
						if entry[0] in installed.keys():
							if int((intalled[entry[0]])[1])<version:
								installed[entry[0]]=entry
						else:
							installed[entry[0]]=entry							
					except:pass		
	print("2. Parsing files from Google Drive. Please Wait...")		
	# print(pths)
	if isinstance(pths, dict):
		db={}
		for i in pths.keys():
			db[i]={'path':pths[i],'TD_name':TDs[i]}	
		files=concurrent_scrapper(filter='',order='name_ascending',remotelib='all',db=db)
	else:
		db={}
		db[pths]={'path':pths,'TD_name':TDs}			
		files=concurrent_scrapper(filter=filter,order='name_ascending',remotelib='all',db=db)
	remotelist=[]		
	for f in files:
		remotelist.append(f[0])
	if prioritize_nsz==True:		
		remotelist=sorted(remotelist, key=lambda x: x[-1])	
		remotelist.reverse()	
	else:
		remotelist.reverse()
	# for f in remotelist:
		# print(f)
	remotegames={}		
	for g in remotelist:
		try:
			entry=listmanager.parsetags(g)
			entry=list(entry)
			entry.append(g)		
			if not entry[0] in remotegames:
				remotegames[entry[0]]=entry
			else:
				v=(remotegames[entry[0]])[1]
				if int(entry[1])>int(v):
					remotegames[entry[0]]=entry		
		except:pass							
	print("3. Searching new updates. Please Wait...")						
	gamestosend={}		
	for g in installed.keys():
		if g.endswith('000') or g.endswith('800'): 
			try:
				updid=g[:-3]+'800'
				if updid in remotegames:
					if updid in installed:
						if ((installed[updid])[1])<((remotegames[updid])[1]):
							if not updid in gamestosend:
								gamestosend[updid]=remotegames[updid]
							else:
								if ((gamestosend[updid])[1])<((remotegames[updid])[1]):
									gamestosend[updid]=remotegames[updid]
					else:
						if not updid in gamestosend:
							gamestosend[updid]=remotegames[updid]
						else:
							if ((gamestosend[updid])[1])<((remotegames[updid])[1]):
								gamestosend[updid]=remotegames[updid]								
			except:pass
		else:
			try:		
				if g in remotegames:
					if ((installed[g])[1])<((remotegames[g])[1]):
						if not g in gamestosend:
							gamestosend[g]=remotegames[g]
						else:
							if ((gamestosend[g])[1])<((remotegames[g])[1]):
								gamestosend[g]=remotegames[g]
			except:pass							
	print("4. Searching new dlcs. Please Wait...")	
	for g in installed.keys():	
		try:
			if g.endswith('000') or g.endswith('800'): 
				baseid=g[:-3]+'000'
			else:
				baseid=(installed[g])[6]
			for k in remotegames.keys():
				try:				
					if not (k.endswith('000') or k.endswith('800')) and not k in installed:
						test=get_dlc_baseid(k)
						if baseid ==test:
							if not k in gamestosend:
								gamestosend[k]=remotegames[k]
							else:
								if ((gamestosend[k])[1])<((remotegames[k])[1]):
									gamestosend[k]=remotegames[k]	
				except BaseException as e:
					# Print.error('Exception: ' + str(e))			
					pass								
		except BaseException as e:
			# Print.error('Exception: ' + str(e))			
			pass
	print("5. List of content that will get installed...")	
	gamepaths=[]
	if len(gamestosend.keys())>0:
		if autoupd_aut==True:	
			for i in sorted(gamestosend.keys()):
				fileid,fileversion,cctag,nG,nU,nD,baseid,path=gamestosend[i]
				bname=os.path.basename(path) 
				gamepaths.append(path)
				g0=[pos for pos, char in enumerate(bname) if char == '[']	
				g0=(bname[0:g0[0]]).strip()
				print(f"   * {g0} [{fileid}][{fileversion}] [{cctag}] - {(bname[-3:]).upper()}")
		else:
			options=[]
			for i in sorted(gamestosend.keys()):			
				fileid,fileversion,cctag,nG,nU,nD,baseid,path=gamestosend[i]
				bname=os.path.basename(path) 
				gamepaths.append(path)
				g0=[pos for pos, char in enumerate(bname) if char == '[']	
				g0=(bname[0:g0[0]]).strip()
				cstring=f"{g0} [{fileid}][{fileversion}] [{cctag}] - {(bname[-3:]).upper()}"
				options.append(cstring)
			if options:
				from python_pick import Picker
				title = 'Select content to install: \n + Press space or right to select entries \n + Press Enter to confirm selection \n + Press E to exit selection \n + Press A to select all entries'				
				picker = Picker(options, title, multi_select=True, min_selection_count=1)
				def end_selection(picker):
					return False,-1
				def select_all(picker):
					return "ALL",-1			
				picker.register_custom_handler(ord('e'),  end_selection)
				picker.register_custom_handler(ord('E'),  end_selection)
				picker.register_custom_handler(ord('a'),  select_all)
				picker.register_custom_handler(ord('A'),  select_all)	
				selected=picker.start()					
			if selected[0]==False:
				print("    User didn't select any files")
				return False					
			if selected[0]=="ALL":		
				pass
			else:
				newgpaths=[]
				for game in selected:
					g=game[1]
					g0=gamepaths[g]
					newgpaths.append(g0)
				gamepaths=newgpaths					
		print("6. Generating text file...")		
		with open(tfile,'w', encoding='utf8') as textfile:
			wpath=''
			for i in gamepaths:
				location=None
				for f in files:
					TD=None;ID=None
					if f[0]==i:	
						location=f[2]
						try:
							ID=f[4]
						except:pass	
						break
				if location==None:
					print(f"Can't find location for {i}")
					continue
				wpath=f"{location}/{i}"
				lib,TD,libpath=get_library_from_path(filename=wpath)
				if ID==None:
					textfile.write(f"{(wpath).strip()}|{TD}\n")
				else:		
					textfile.write(f"{(wpath).strip()}|{TD}|{ID}\n")	
		print("7. Triggering installer on loop mode.")
		print("   Note:If you interrupt the list use normal install mode to continue list")	
		loop_install(tfile,destiny=destiny,outfolder=None,ch_medium=ch_medium,check_fw=True,patch_keygen=False,ch_base=False,ch_other=False,checked=True)
	else:
		print("\n   --- DEVICE IS UP TO DATE ---")					
def fichier_install(url,destiny="SD",ch_medium=True,ch_base=False,ch_other=False,installed_list=False):
	check_connection()
	if not os.path.exists(_1fichier_token):
		sys.exit("No 1fichier token setup")
	with open(_1fichier_token,'rt',encoding='utf8') as tfile:
		token=(tfile.readline().strip())
	if token==None:
		sys.exit("Missing 1fichier token")		
	APIkey=token
	auth={'Authorization':f'Bearer {APIkey}','Content-Type':'application/json'}
	session = requests.session()
	download_params = {
		'url' : url,
		'inline' : 0,
		'cdn' : 0,
		'restrict_ip':  0,
		'no_ssl' : 0,
	}			
	info_params={
		'url' : url	
	}
	r=session.post('https://api.1fichier.com/v1/file/info.cgi',json=info_params,headers=auth)
	info_dict=r.json()
	# print(info_dict)
	sz=info_dict['size']
	name=info_dict['filename']
	r=session.post('https://api.1fichier.com/v1/download/get_token.cgi',json=download_params,headers=auth)
	dict_=r.json()
	# print(dict_)
	ext=name.split('.')
	ext=ext[-1]
	if not name.endswith('nsp') and not name.endswith('nsz'):
		sys.exit(f"Extension not supported for direct instalation {ext} in {name}")			
	if not dict_['status']=="OK":
		sys.exit(f"API call returned {dict_['status']}")			
	URL=dict_['url']
	print("- Retrieving Space on device")
	SD_ds,SD_fs,NAND_ds,NAND_fs,FW,device=get_storage_info()
	print("- Calculating Installed size")	
	filesize=int(sz)
	if destiny=="SD":
		print(f"  * SD free space: {SD_fs} ({sq_tools.getSize(SD_fs)})")	
		print(f"  * File size: {filesize} ({sq_tools.getSize(filesize)})")		
		if filesize>SD_fs:
			if filesize<NAND_fs and ch_medium==True:
				print("  Not enough space on SD. Changing target to EMMC")
				print(f"  * EMMC free space: {NAND_fs} ({sq_tools.getSize(NAND_fs)})")						
				destiny="NAND"
			elif  ch_medium==False:	
				sys.exit("   NOT ENOUGH SPACE SD STORAGE")				
			else:
				sys.exit("   NOT ENOUGH SPACE ON DEVICE")				
	else:
		print(f"  * EMMC free space: {NAND_fs} ({sq_tools.getSize(NAND_fs)})")	
		print(f"  * File size: {filesize} ({sq_tools.getSize(filesize)})")		
		if filesize>NAND_fs:		
			if filesize<SD_fs and ch_medium==True:
				print("  Not enough space on EMMC. Changing target to SD")			
				print(f"  * SD free space: {SD_fs} ({sq_tools.getSize(SD_fs)})")					
				destiny="SD"
			elif  ch_medium==False:	
				sys.exit("   NOT ENOUGH SPACE EMMC STORAGE")							
			else:
				sys.exit("   NOT ENOUGH SPACE ON DEVICE")			
	if installed_list!=False:
		try:
			fileid,fileversion,cctag,nG,nU,nD,baseid=listmanager.parsetags(name)
			fileversion=int(fileversion)
			if fileid.endswith('000') and fileversion==0 and fileid in installed_list.keys() and ch_base==True:
				print("Base game already installed. Skipping...")
				return False	
			elif fileid.endswith('000') and fileid in installed_list.keys() and ch_other==True:
				updid=fileid[:-3]+'800'
				if fileversion>((installed_list[fileid])[2]):
					print("Asking DBI to delete previous content")
					process=subprocess.Popen([nscb_mtp,"DeleteID","-ID",fileid])	
					while process.poll()==None:
						if process.poll()!=None:
							process.terminate();					
					process=subprocess.Popen([nscb_mtp,"DeleteID","-ID",updid])		
					while process.poll()==None:
						if process.poll()!=None:
							process.terminate();					
				else:
					print("The update is a previous version than the installed on device.Skipping..")
					listmanager.striplines(tfile,counter=True)
					return False		
			elif ch_other==True	and fileid in installed_list.keys():
				if fileversion>((installed_list[fileid])[2]):
					print("Asking DBI to delete previous update")
					process=subprocess.Popen([nscb_mtp,"DeleteID","-ID",fileid])					
					while process.poll()==None:
						if process.poll()!=None:
							process.terminate();
				else:
					print("The update is a previous version than the installed on device.Skipping..")
					listmanager.striplines(tfile,counter=True)
					return False	
		except:pass				
	process=subprocess.Popen([nscb_mtp,"fichierInstall","-ori",URL,"-dst",destiny,"-name",name,"-size",str(sz)])
	while process.poll()==None:
		if process.poll()!=None:
			process.terminate();		
def public_gdrive_install(filepath,destiny="SD",truecopy=True,outfolder=None,ch_medium=True,check_fw=True,patch_keygen=False,ch_base=False,ch_other=False,installed_list=False):
	check_connection()
	lib,TD,libpath=get_cache_lib()
	if lib==None:
		sys.exit(f"Google Drive Public Links are only supported via cache folder")	
	filename=addtodrive(filepath,truecopy=truecopy)
	ID,name,type,size,md5,remote=DrivePrivate.get_Data(filename,TD=TD,Print=False)	
	token=remote.access_token
	name=remote.name
	sz=remote.size
	URL='https://www.googleapis.com/drive/v3/files/'+remote.ID+'?alt=media'	
	ext=name.split('.')
	ext=ext[-1]
	if not name.endswith('nsp') and not name.endswith('nsz') and not  name.endswith('xci') and not name.endswith('xcz'):
		print(f"Extension not supported for direct instalation {ext} in {name}")
		return False
	print("- Retrieving Space on device")
	SD_ds,SD_fs,NAND_ds,NAND_fs,FW,device=get_storage_info()
	print("- Calculating Installed size")	
	filesize=int(sz)
	if destiny=="SD":
		print(f"  * SD free space: {SD_fs} ({sq_tools.getSize(SD_fs)})")	
		print(f"  * File size: {filesize} ({sq_tools.getSize(filesize)})")		
		if filesize>SD_fs:
			if filesize<NAND_fs and ch_medium==True:
				print("  Not enough space on SD. Changing target to EMMC")
				print(f"  * EMMC free space: {NAND_fs} ({sq_tools.getSize(NAND_fs)})")						
				destiny="NAND"
			elif  ch_medium==False:	
				sys.exit("   NOT ENOUGH SPACE SD STORAGE")				
			else:
				sys.exit("   NOT ENOUGH SPACE ON DEVICE")				
	else:
		print(f"  * EMMC free space: {NAND_fs} ({sq_tools.getSize(NAND_fs)})")	
		print(f"  * File size: {filesize} ({sq_tools.getSize(filesize)})")		
		if filesize>NAND_fs:		
			if filesize<SD_fs and ch_medium==True:
				print("  Not enough space on EMMC. Changing target to SD")			
				print(f"  * SD free space: {SD_fs} ({sq_tools.getSize(SD_fs)})")					
				destiny="SD"
			elif  ch_medium==False:	
				sys.exit("   NOT ENOUGH SPACE EMMC STORAGE")							
			else:
				sys.exit("   NOT ENOUGH SPACE ON DEVICE")
	kgwarning=False						
	if check_fw==True:	
		try:
			cnmtdata,files_list,remote=DriveTools.get_cnmt_data(file=remote)		
			keygeneration=int(cnmtdata['keygeneration'])
			if FW!='unknown':	
				try:
					FW_RSV,RRSV=sq_tools.transform_fw_string(FW)
					FW_kg=sq_tools.kg_by_RSV(FW_RSV)
				except BaseException as e:
					Print.error('Exception: ' + str(e))
					FW='unknown'
					FW_kg='unknown'
					pass
			if FW!='unknown' and FW_kg!='unknown':			
				if int(keygeneration)>int(FW_kg):
					kgwarning=True
					tgkg=int(FW_kg)
				else:
					tgkg=keygeneration
			else:
				tgkg=keygeneration
			print(f"- Console Firmware: {FW} ({FW_RSV}) - keygen {FW_kg})")		
			print(f"- File keygeneration: {keygeneration}")				
			if kgwarning==True:
				print("File requires a higher firmware. Skipping...")
				return False
		except:	
			print("Error getting cnmtdata from file")		
	if installed_list!=False:
		try:
			fileid,fileversion,cctag,nG,nU,nD,baseid=listmanager.parsetags(name)
			fileversion=int(fileversion)
			if fileid.endswith('000') and fileversion==0 and fileid in installed_list.keys() and ch_base==True:
				print("Base game already installed. Skipping...")
				return False	
			elif fileid.endswith('000') and fileid in installed_list.keys() and ch_other==True:
				updid=fileid[:-3]+'800'
				if fileversion>((installed_list[fileid])[2]):
					print("Asking DBI to delete previous content")
					process=subprocess.Popen([nscb_mtp,"DeleteID","-ID",fileid])	
					while process.poll()==None:
						if process.poll()!=None:
							process.terminate();					
					process=subprocess.Popen([nscb_mtp,"DeleteID","-ID",updid])		
					while process.poll()==None:
						if process.poll()!=None:
							process.terminate();					
				else:
					print("The update is a previous version than the installed on device.Skipping..")
					listmanager.striplines(tfile,counter=True)
					return False		
			elif ch_other==True	and fileid in installed_list.keys():
				if fileversion>((installed_list[fileid])[2]):
					print("Asking DBI to delete previous update")
					process=subprocess.Popen([nscb_mtp,"DeleteID","-ID",fileid])					
					while process.poll()==None:
						if process.poll()!=None:
							process.terminate();
				else:
					print("The update is a previous version than the installed on device.Skipping..")
					listmanager.striplines(tfile,counter=True)
					return False	
		except:pass			
	if name.endswith('xci') or name.endswith('xcz'):
		from mtpxci_remote import install_xci_csv
		install_xci_csv(remote=remote,destiny=destiny,cachefolder=outfolder)
	else:			
		process=subprocess.Popen([nscb_mtp,"DriveInstall","-ori",URL,"-dst",destiny,"-name",name,"-size",sz,"-tk",token])
		while process.poll()==None:
			if process.poll()!=None:
				process.terminate();