def add_file_to_all_SA(SAfolder=None, ID=None, parent='root'): if os.path.exists(SAfolder): from listmanager import folder_to_list jfiles = folder_to_list(SAfolder, ['json']) for j in jfiles: add_to_drive(json_file=j, parent=parent, ID=ID, makecopy=False) print('{} Added to {}'.format(ID, j))
def add_signed_footer(message=None,ifolder=None,tfile=None,ext='all',rewrite=False): from sq_tools import add_signed_footer as sign from ast import literal_eval as eval if ext=='all': ext=['nsp','nsx','nsz','xci','xcz'] else: if isinstance(ext, list): ext=ext else: try: ext=eval(ext) except:pass ext=ext.split(',') if ifolder!=None: try: ifolder=eval(ifolder) except:pass files=listmanager.folder_to_list(ifolder,ext) elif tfile!=None: try: tfile=eval(tfile) except:pass files=read_lines_to_list(tfile,all=True) else: return False for filepath in files: try: sign(filepath,message,rewrite) except: print('Error in '+filepath)
def rebuild_nsp(ifolder, ofolder, buffer=65536, delta=False, xml_gen=False, export='nsp'): extlist = ['nsp', 'nsz'] files = listmanager.folder_to_list(ifolder, extlist) from Fs import Nsp import decompressor total = len(files) for filepath in files: if filepath.endswith('nsp'): basename = os.path.basename(os.path.abspath(filepath)) endfile = os.path.join(ofolder, basename) print('Processing: ' + filepath) f = Nsp(filepath) f.rebuild(buffer, endfile, delta, False, xml_gen) f.flush() f.close() elif filepath.endswith('nsz'): basename = os.path.basename(os.path.abspath(filepath)) endname = basename[:-1] + 'p' endname = os.path.join(ofolder, endname) decompressor.decompress_nsz(filepath, endname, buffer, delta, xml_gen) total -= 1 print("**********************************************************") print(('Still {} files to process').format(str(total))) 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
def decompress_nsz(ifolder, ofolder, buffer=65536, delta=False, xml_gen=False): extlist = ['nsz'] files = listmanager.folder_to_list(ifolder, extlist) import decompressor for filepath in files: basename = os.path.basename(os.path.abspath(filepath)) endname = basename[:-1] + 'p' endname = os.path.join(ofolder, endname) decompressor.decompress_nsz(filepath, endname, buffer, delta, xml_gen)
def search_with_filter(folder_paths, extlist=['nsp', 'nsz', 'xci', 'xcz']): filepaths = [] title = 'Add a search filter?: ' options = ['Yes', 'No'] selected = pick(options, title, min_selection_count=1) response = selected[0] if response == 'No': for fo in folder_paths: rlist = listmanager.folder_to_list(fo, extlist) filepaths = [*filepaths, *rlist] return filepaths else: clear_Screen() About() ck = input('INPUT SEARCH FILTER: ') for fo in folder_paths: rlist = listmanager.folder_to_list(fo, extlist, ck) filepaths = [*filepaths, *rlist] return filepaths
def scrape_local_libs(): from listmanager import folder_to_list db = libraries(local_lib_file) if db == False: return results = [] for entry in db: path = db[entry]['path'] res = folder_to_list(path, 'all') results += res local_lib_2html(entry, res) local_lib_2html('all', results)
def foldercompress(ifolder, ofolder = None, level = 17, threads = 0, t=['nsp']): mylist=listmanager.folder_to_list(ifolder,t) counter=len(mylist) for item in mylist: print(item) if ofolder is None: nszPath = item[0:-1] + 'z' else: nszPath = os.path.join(ofolder, os.path.basename(item[0:-1] + 'z')) compress(item,ofolder=None,level=level,threads=threads,ofile=nszPath) counter-=1 print('\nStill %d files to compress\n'%(counter))
def token_picker(): files = folder_to_list(credentials_dir, "all") # print(files) tokens = list() names = list() for file in files: bname = os.path.basename(os.path.abspath(file)) test = bname.split(".") if len(test) == 1 and file not in tokens: tokens.append(file) names.append(str(os.path.basename(os.path.abspath(file)))) if len(names) > 1: title = 'Pick an account (press SPACE\RIGHT to mark\\unmark, ENTER to continue): ' options = names selected = pick(options, title, min_selection_count=1) tok = names[selected[1]] elif len(names) == 1: tok = names[0] else: tok = False return tok
def read_footer(ifolder=None,tfile=None,ext='all'): from sq_tools import read_footer from ast import literal_eval as eval if ext=='all': ext=['nsp','nsx','nsz','xci','xcz'] else: if isinstance(ext, list): ext=ext else: try: ext=eval(ext) except:pass ext=ext.split(',') if ifolder!=None: files=listmanager.folder_to_list(ifolder,ext) elif tfile!=None: files=read_lines_to_list(tfile,all=True) else: return False for filepath in files: read_footer(filepath)
def scrape(reg_folder): meta_filepaths = [] file_list = folder_to_list(reg_folder, 'all', filter='00') # print(file_list) File_DB = return_nca_data(file_list) # print(File_DB.keys()) for e in File_DB: dic = File_DB[e] if str(dic['content_type']) == 'Content.META': get_cnmt_data cnmt_dict = get_cnmt_data(dic) ncadata = cnmt_dict['ncadata'] complete = True for d in ncadata: if d['NCAtype'] == "DeltaFragment": continue ncid = d['NcaId'] # print(f"{ncid}") if not (f"{str(ncid).lower()}.nca" in File_DB.keys()) and not ( f"{str(ncid).lower()}.cnmt.nca" in File_DB.keys()): complete = False print(f"{dic['titleid']} - {e} - complete:{complete}")
def check_xci_certs(ifolder, tfile, tfile2): from listmanager import folder_to_list, striplines, read_lines_to_list from Fs import Xci import os if not os.path.exists(tfile): xci_files = folder_to_list(ifolder, ['xci']) with open(tfile, "w", encoding='utf8') as t: for file in xci_files: t.write(file + '\n') else: xci_files = read_lines_to_list(tfile, all=True) counter = len(xci_files) for file in xci_files: try: xci = Xci(file) if not xci.gamecardCert.Cert_is_fake: print(f"{file} has personalized certificate") with open(tfile2, "a", encoding='utf8') as t: t.write(file + '\n') else: print(f"{file} has a wiped certificate") xci.close() counter -= 1 striplines(tfile, 1, True) except: try: with open(tfile2, "a", encoding='utf8') as t: t.write("Error:" + file + '\n') except: pass counter -= 1 striplines(tfile, 1, True) try: os.remove(tfile) except: pass
def dump_title(input_folder, output=None, ofolder=None, root_r_PATH=False): # if output==None and ofolder==None: # raise Exception("User didn't set output") file_list = folder_to_list(input_folder, 'all', filter='00') # print(file_list) meta_filepath, meta_filename, File_DB = return_meta_file(file_list) if meta_filename == False: print("- Can't find a meta file") else: print(f"- Meta file is {meta_filename} in {meta_filepath}") title_name = None for e in File_DB: dic = File_DB[e] if dic['content_type'] == 'Content.CONTROL': title_name = get_nsx_name(dic) break cnmt_dict = get_cnmt_data(File_DB[meta_filename]) titleid = cnmt_dict['titleid'] version = cnmt_dict['titleversion'] if title_name == None: import nutdb title_name = nutdb.get_dlcname(titleid) nsx_name = f"{title_name} [{titleid}][v{version}].nsx" print(nsx_name)
def back_up_saves(backup_all=False, inline=False, tidandver=True, romaji=True, outfolder=None): import zipfile from datetime import datetime 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 outfolder == None: outfolder = pick_download_folder() if not os.path.exists(outfolder): os.makedirs(outfolder) process = subprocess.Popen([ nscb_mtp, "ShowSaveGames", "-saves", valid_saves_cache, "-show", "False" ]) while process.poll() == None: if process.poll() != None: process.terminate() if not os.path.exists(valid_saves_cache): sys.exit("Savegames couldn't be retrieved") valid_saves = [] with open(valid_saves_cache, 'rt', encoding='utf8') as tfile: for line in tfile: valid_saves.append(line.strip()) if backup_all == False: title = 'Select saves to backup: \n + Press space or right to select content \n + Press E to finish selection' options = valid_saves picker = Picker(options, title, multi_select=True, min_selection_count=1) def end_selection(picker): return False, -1 picker.register_custom_handler(ord('e'), end_selection) picker.register_custom_handler(ord('E'), end_selection) selected = picker.start() if selected[0] == False: print(" User didn't select any games") return False else: selected = [] for i in range(len(valid_saves)): selected.append([valid_saves[i], i]) print("- Retrieving registered to get TitleIDs...") 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") if tidandver == 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: version = 0 try: tid = (str(row[id]).upper())[2:] tid = tid[:-3] + '000' version = int(row[ver]) name = str(row[tname]) if name in dbi_dict: if version < ((dbi_dict[name])['version']): continue dbi_dict[name] = { 'tid': tid, 'version': version, 'name': name } except: pass counter = len(selected) for file in selected: if tidandver == True: print(f'- Searching "{file[0]}" in registered data') titleid = "" version = "" name = file[0] try: titleid = ((dbi_dict[file[0]])['tid']) titleid = f'[{titleid}]' version = str((dbi_dict[file[0]])['version']) version = f'[v{version}]' except: pass game = f"{name} {titleid}{version}" else: game = f"{name}" game = sanitize(game, romaji) if inline == False: dmpfolder = os.path.join(outfolder, game) else: dmpfolder = outfolder tmpfolder = os.path.join(dmpfolder, 'tmp') if not os.path.exists(dmpfolder): os.makedirs(dmpfolder) if not os.path.exists(tmpfolder): os.makedirs(tmpfolder) process = subprocess.Popen( [nscb_mtp, "BackSaves", "-sch", file[0], "-dst", tmpfolder]) while process.poll() == None: if process.poll() != None: process.terminate() counter -= 1 subfolders = [f.path for f in os.scandir(tmpfolder) if f.is_dir()] for folder in subfolders: dname = os.path.basename(folder) timedate = datetime.now() timedate = timedate.strftime("[%Y.%m.%d @ %H.%M.%S]") zipname = f"{game}{timedate}[{dname}].zip" output = os.path.join(dmpfolder, zipname) print(f"- Zipping {folder} to {output}") file_list = listmanager.folder_to_list(folder, extlist='all') if not file_list: continue z = zipfile.ZipFile(output, "w", zipfile.ZIP_DEFLATED) basedir = os.path.dirname(folder) for dirpath, dirnames, filenames in os.walk(folder): for filename in filenames: filePath = os.path.join(dirpath, filename) dirname = filePath.replace(folder, '') dirname = dirname[0:] if os.path.isfile(filePath): z.write(filePath, dirname) z.close() try: shutil.rmtree(tmpfolder, ignore_errors=True) except: pass print('...................................................') print('STILL ' + str(counter) + ' FILES TO PROCESS') print('...................................................')
def remote_select_from_cache(tfile): from workers import concurrent_scrapper cache_is_setup = False if not os.path.exists(remote_lib_cache): os.makedirs(remote_lib_cache) jsonlist = listmanager.folder_to_list(remote_lib_cache, extlist=['json']) if not jsonlist: print("Cache wasn't found. Generating cache up...") from workers import concurrent_cache concurrent_cache() jsonlist = listmanager.folder_to_list(remote_lib_cache, extlist=['json']) if not jsonlist: sys.exit("Can't setup remote cache. Are libraries set up?") libnames = [] for j in jsonlist: bname = os.path.basename(j) bname = bname.replace('.json', '') libnames.append(bname) title = 'Select libraries to search: \n + Press space or right to select content \n + Press Enter to confirm selection \n + Press E to exit selection \n + Press A to select all libraries' db = libraries(remote_lib_file) options = libnames picker = Picker(options, title, multi_select=True, min_selection_count=1) def end_selection(picker): return False, -1 def select_all(picker): return True, libnames 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 libraries") return False, False if selected[0] == True: cachefiles = jsonlist else: cachefiles = [] for entry in selected: fname = entry[0] + '.json' fpath = os.path.join(remote_lib_cache, fname) cachefiles.append(fpath) cachedict = {} for cach in cachefiles: with open(cach) as json_file: data = json.load(json_file) for entry in data: if not entry in cachedict: cachedict[entry] = data[entry] # for k in cachedict.keys(): # print(k) order = pick_order() if order == False: return False options = [] if order == 'name_ascending': options = sorted(cachedict, key=lambda x: cachedict[x]['filepath']) elif order == 'name_descending': options = sorted(cachedict, key=lambda x: cachedict[x]['filepath']) options.reverse() elif order == 'size_ascending': options = sorted(cachedict, key=lambda x: cachedict[x]['size']) elif order == 'size_descending': options = sorted(cachedict, key=lambda x: cachedict[x]['size']) options.reverse() elif order == 'date_ascending': options = sorted(cachedict, key=lambda x: cachedict[x]['date']) elif order == 'date_descending': options = sorted(cachedict, key=lambda x: cachedict[x]['date']) options.reverse() options = remote_interface_filter_local(options) print(" * Entering File Picker") title = 'Select content to install or transfer: \n + Press space or right to select content \n + Press Enter to confirm selection \n + Press E to exit selection' picker = Picker(options, title, multi_select=True, min_selection_count=1) def end_selection(picker): return False, -1 picker.register_custom_handler(ord('e'), end_selection) picker.register_custom_handler(ord('E'), end_selection) selected = picker.start() if selected[0] == False: print(" User didn't select any files") return False with open(tfile, 'a') as textfile: for f in selected: fpath = (cachedict[f[0]])['filepath'] textfile.write(fpath + '\n')
def search_local_lib(value,library): if library=='None': html='<p style="margin-bottom: 2px;margin-top: 3px"><strong style="margin-left: 12px">You need to create a library config file first</strong></p>' eel.load_local_results(html) return try: db=libraries(local_lib_file) if db==False: eel.load_local_results(False) return if not library.lower()=='all': path=db[library]['path'] print("* Searching library {}".format(library)) sys.stdout.flush() results=folder_to_list(path,'all',value) sr=sortbyname(results) html='<ul style="margin-bottom: 2px;margin-top: 3px; list-style-type: none;">' i=0 print(" - Retrieved {} files".format(str(len(results)))) sys.stdout.flush() for it in sorted(sr.keys()): i+=1;type='' item=sr[it] item2=' '+it if item2.endswith('.nsp'): type='<span class="bg-darkBlue fg-white"> nsp </span>' elif item2.endswith('.xci'): type='<span class="bg-darkRed fg-white"> xci  </span>' var='local_res_'+str(i) html+='<li style="margin-bottom: 2px;margin-top: 3px" onclick="start_from_library({})"><span id="{}" style="display:none">{}</span>{}<strong>{}</strong></li>'.format(var,var,item,type,item2) html+='</ul>' else: results=[] for entry in db: path=db[entry]['path'] print("* Searching library {}".format(entry)) sys.stdout.flush() res=folder_to_list(path,'all',value) print(" - Retrieved {} files".format(str(len(res)))) sys.stdout.flush() results+=res sr=sortbyname(results) html='<ul style="margin-bottom: 2px;margin-top: 3px; list-style-type: none;">' i=0 for it in sorted(sr.keys()): i+=1;type='' item=sr[it] item2=' '+it if item2.endswith('.nsp'): type='<span class="bg-darkBlue fg-white"> nsp </span>' elif item2.endswith('.xci'): type='<span class="bg-darkRed fg-white"> xci  </span>' var='local_res_'+str(i) html+='<li style="margin-bottom: 2px;margin-top: 3px" onclick="start_from_library({})"><span id="{}" style="display:none">{}</span>{}<strong>{}</strong></li>'.format(var,var,item,type,item2) # print(item) html+='</ul>' eel.load_local_results(html) return except BaseException as e: Print.error('Exception: ' + str(e)) sys.stdout.flush()
def generate_multixci_and_transfer(tfile=None,outfolder=None,destiny="SD",kgpatch=False,verification=False): if destiny==False or destiny=="pick" or destiny=="": destiny=pick_transfer_folder() if destiny=="SD": destiny="1: External SD Card\\" from mtpinstaller import get_storage_info,get_DB_dict tgkg=0;kgwarning=False if tfile=="": tfile=None if tfile==None: print("File input = null") return False if not os.path.exists(tfile): sys.exit(f"Couldn't find {tfile}") if outfolder=="": outfolder=None if outfolder==None: outfolder=cachefolder if not os.path.exists(cachefolder): os.makedirs(cachefolder) if not os.path.exists(outfolder): os.makedirs(outfolder) for f in os.listdir(outfolder): fp = os.path.join(outfolder, f) try: shutil.rmtree(fp) except OSError: os.remove(fp) file_list=listmanager.read_lines_to_list(tfile,all=True) if verification==True or str(verification).upper()=="HASH": verdict=False for fp in file_list: if str(verification).upper()=="HASH": verdict,isrestored,cnmt_is_patched=file_verification(fp,hash=True) else: verdict,isrestored,cnmt_is_patched=file_verification(fp) if verdict==False: print(f"{fp} didn't pass verification. Skipping {tfile}") return False dopatch=False print("- Retrieving Space on device") SD_ds,SD_fs,NAND_ds,NAND_fs,FW,device=get_storage_info() print("- Calculating Size") fullxcisize=0;maxkg=0 for fp in file_list: head_xci_size,keygeneration,sz=get_header_size(fp) installedsize=head_xci_size+sz fullxcisize+=installedsize if int(maxkg)<int(keygeneration): maxkg=keygeneration print(f" * SD free space: {SD_fs} ({sq_tools.getSize(SD_fs)})") print(f" * File installed size: {installedsize} ({sq_tools.getSize(installedsize)})") if installedsize>SD_fs: sys.exit(" NOT ENOUGH SPACE SD STORAGE") if kgpatch==True: 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}") else: tgkg=keygeneration if kgwarning==True: print("File requires a higher firmware. It'll will be prepatch") dopatch=True keypatch=int(tgkg) if isExe==False: process0=subprocess.Popen([sys.executable,squirrel,"-b","65536","-pv","true","-kp",str(keypatch),"--RSVcap","268435656","-fat","exfat","-fx","files","-ND","true","-t","xci","-o",outfolder,"-tfile",tfile,"-roma","TRUE","-dmul","calculate"]) else: process0=subprocess.Popen([squirrel,"-b","65536","-pv","true","-kp",str(keypatch),"--RSVcap","268435656","-fat","exfat","-fx","files","-ND","true","-t","xci","-o",outfolder,"-tfile",tfile,"-roma","TRUE","-dmul","calculate"]) while process0.poll()==None: if process0.poll()!=None: process0.terminate(); files2transfer=listmanager.folder_to_list(outfolder,['xci']) for f in files2transfer: bname=str(os.path.basename(f)) destinypath=os.path.join(destiny,bname) process=subprocess.Popen([nscb_mtp,"Transfer","-ori",f,"-dst",destinypath]) while process.poll()==None: if process.poll()!=None: process.terminate(); try: for f in os.listdir(outfolder): fp = os.path.join(outfolder, f) try: shutil.rmtree(fp) except OSError: os.remove(fp) except:pass
def get_files_from_walk(tfile=None, extlist=['nsp', 'nsz', 'xci', 'xcz'], filter=False, recursive=False, doPrint=False): if not isinstance(extlist, list): if str(extlist).lower() != 'all': ext = extlist.split() extlist = [] for x in ext: extlist.append(x) folder, rec = folder_walker() if folder == False: return False if rec == True: recursive = True print("Parsing files. Please wait...") title = 'Add a search filter?: ' options = ['Yes', 'No'] selected = pick(options, title, min_selection_count=1) response = selected[0] if response == 'No': pass else: clear_Screen() About() filter = input('INPUT SEARCH FILTER: ') if recursive == False: files = listmanager.nextfolder_to_list(folder, extlist=extlist, filter=filter) else: files = listmanager.folder_to_list(folder, extlist=extlist, filter=filter) if not files: sys.exit("Query didn't return any files") order = pick_order() if order == False: return False filedata = {} for file in files: try: fname = os.path.basename(file) fsize = os.path.getsize(file) fdate = os.path.getctime(file) entry = { 'filepath': file, 'filename': fname, 'size': fsize, 'date': fdate } if not fname in filedata: filedata[fname] = entry except: pass options = [] if order == 'name_ascending': options = sorted(filedata, key=lambda x: filedata[x]['filename']) elif order == 'name_descending': options = sorted(filedata, key=lambda x: filedata[x]['filename']) options.reverse() elif order == 'size_ascending': options = sorted(filedata, key=lambda x: filedata[x]['size']) elif order == 'size_descending': options = sorted(filedata, key=lambda x: filedata[x]['size']) options.reverse() elif order == 'date_ascending': options = sorted(filedata, key=lambda x: filedata[x]['date']) elif order == 'date_descending': options = sorted(filedata, key=lambda x: filedata[x]['date']) options.reverse() title = 'Select content: \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 newgpaths = [] if selected[0] == "ALL": for game in options: newgpaths.append(os.path.join(folder, game)) else: for game in selected: newgpaths.append(os.path.join(folder, game[0])) if tfile != None: with open(tfile, 'w', encoding='utf8') as textfile: for i in newgpaths: textfile.write((i).strip() + "\n") if doPrint != False: for i in newgpaths: print(i) return newgpaths
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 ---")
def generate_xci_and_transfer(filepath=None,outfolder=None,destiny="SD",kgpatch=False,verification=False): if destiny=="SD": destiny="1: External SD Card\\" from mtpinstaller import get_storage_info,get_DB_dict tgkg=0;kgwarning=False if filepath=="": filepath=None if filepath==None: print("File input = null") return False if outfolder=="": outfolder=None if outfolder==None: outfolder=cachefolder if not os.path.exists(cachefolder): os.makedirs(cachefolder) if not os.path.exists(outfolder): os.makedirs(outfolder) for f in os.listdir(outfolder): fp = os.path.join(outfolder, f) try: shutil.rmtree(fp) except OSError: os.remove(fp) if verification==True or str(verification).upper()=="HASH": if str(verification).upper()=="HASH": verdict,isrestored,cnmt_is_patched=file_verification(filepath,hash=True) else: verdict,isrestored,cnmt_is_patched=file_verification(filepath) if verdict==False: print("File didn't pass verification. Skipping...") return False dopatch=False print("- Retrieving Space on device") SD_ds,SD_fs,NAND_ds,NAND_fs,FW,device=get_storage_info() print("- Calculating Size") head_xci_size,keygeneration,sz=get_header_size(filepath) installedsize=head_xci_size+sz print(f" * SD free space: {SD_fs} ({sq_tools.getSize(SD_fs)})") print(f" * File installed size: {installedsize} ({sq_tools.getSize(installedsize)})") if installedsize>SD_fs: sys.exit(" NOT ENOUGH SPACE SD STORAGE") if kgpatch==True: 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}") else: tgkg=keygeneration if kgwarning==True: print("File requires a higher firmware. It'll will be prepatch") dopatch=True keypatch=int(tgkg) tname=str(os.path.basename(filepath))[:-3]+'xci' tmpfile=os.path.join(outfolder,tname) if isExe==False: process0=subprocess.Popen([sys.executable,squirrel,"-lib_call","mtp.mtpxci","generate_and_transfer_st1","-xarg",filepath,outfolder,str(keypatch)]) else: process0=subprocess.Popen([squirrel,"-lib_call","mtp.mtpxci","generate_and_transfer_st1","-xarg",filepath,outfolder,str(keypatch)]) while process0.poll()==None: if process0.poll()!=None: process0.terminate(); if isExe==False: process1=subprocess.Popen([sys.executable,squirrel,"-renf",tmpfile,"-t","xci","-renm","force","-nover","xci_no_v0","-addl","false","-roma","TRUE"]) else: process1=subprocess.Popen([sys.executable,squirrel,"-renf",tmpfile,"-t","xci","-renm","force","-nover","xci_no_v0","-addl","false","-roma","TRUE"]) while process1.poll()==None: if process1.poll()!=None: process1.terminate(); files2transfer=listmanager.folder_to_list(outfolder,['xci']) for f in files2transfer: bname=str(os.path.basename(f)) destinypath=os.path.join(destiny,bname) process=subprocess.Popen([nscb_mtp,"Transfer","-ori",f,"-dst",destinypath]) while process.poll()==None: if process.poll()!=None: process.terminate(); try: for f in os.listdir(outfolder): fp = os.path.join(outfolder, f) try: shutil.rmtree(fp) except OSError: os.remove(fp) except:pass