def downloadThread(i): if not hasCdn: return Print.info('starting thread ' + str(i)) global status while Config.isRunning and not Titles.queue.empty(): try: id = Titles.queue.shift() if id and Titles.contains(id): activeDownloads[i] = 1 t = Titles.get(id) path = cdn.downloadTitle(t.id.lower(), None, t.key) if path and os.path.isfile(path): nsp = Fs.Nsp(path, None) nsp.move() Nsps.save() if status is not None: status.add() activeDownloads[i] = 0 else: time.sleep(1) except KeyboardInterrupt: pass except BaseException as e: Print.error('downloadThread exception: ' + str(e)) traceback.print_exc(file=sys.stdout) activeDownloads[i] = 0 Print.info('ending thread ' + str(i))
def organize(): nut.initTitles() nut.initFiles() #scan() Print.info('organizing') for k, f in Nsps.files.items(): #print('moving ' + f.path) #Print.info(str(f.hasValidTicket) +' = ' + f.path) f.move() for id, t in Titles.data().items(): files = t.getFiles() if len(files) > 1: #Print.info("%d - %s - %s" % (len(files), t.id, t.name)) latest = t.getLatestFile() if not latest: continue for f in files: if f.path != latest.path: f.moveDupe() Print.info('removing empty directories') Nsps.removeEmptyDir('.', False) Nsps.save()
def downloadThread(i): Print.info('starting thread ' + str(i)) global status while Config.isRunning: try: id = Titles.queue.shift() if id and Titles.contains(id): activeDownloads[i] = 1 t = Titles.get(id) path = CDNSP.download_game(t.id.lower(), t.lastestVersion(), t.key, True, '', True) if os.path.isfile(path): nsp = Fs.Nsp(path, None) nsp.move() Nsps.files[nsp.path] = nsp Nsps.save() status.add() activeDownloads[i] = 0 else: time.sleep(1) except KeyboardInterrupt: pass except BaseException as e: Print.error(str(e)) activeDownloads[i] = 0 Print.info('ending thread ' + str(i))
def scan(): global hasScanned hasScanned = True initFiles() r = 0 for path in Config.paths.scan: r += Nsps.scan(path) Nsps.save() return r
def compressWorker(q, level, output, totalStatus): while not q.empty(): try: path = q.get(block=False) totalStatus.add(1) nszFile = compress(path, level, output) if nszFile: nsp = Fs.Nsp(nszFile, None) nsp.hasValidTicket = True nsp.move(forceNsp=True) Nsps.files[nsp.path] = nsp Nsps.save() except queue.Empty as e: return except BaseException as e: Print.info('COMPRESS WORKER EXCEPTION: ' + str(e)) traceback.print_exc(file=sys.stdout)
def scan(scanTitles=False): global hasScanned hasScanned = True if scanTitles == True: initTitles() refreshRegions() importRegion(Config.region, Config.language) initFiles() r = 0 for path in Config.paths.scan: r += Nsps.scan(path) Nsps.save() return r
def pullWorker(q, s): while True: if q.empty(): break nsp = q.get() if not nsp: break try: hasValidTicket = nsp.hasValidTicket tmpFile = getName(nsp.titleId, nsp.version, path=nsp.path) Print.info('Downloading ' + nsp.path) if Config.dryRun: continue if Config.download.fileSizeMax is not None and nsp.getFileSize( ) > Config.download.fileSizeMax: continue if Config.download.fileSizeMin is not None and nsp.getFileSize( ) < Config.download.fileSizeMin: continue with open(tmpFile, 'wb') as f: serveFile(f, nsp.downloadPath, os.path.basename(nsp.path)) nsp = Fs.Nsp(tmpFile, None) nsp.hasValidTicket = hasValidTicket nsp.move(forceNsp=hasValidTicket) Nsps.files[nsp.path] = nsp Nsps.save() except BaseException as e: Print.error('FTP SYNC EXCEPTION: ' + str(e)) #raise #TODO s.add() Print.info('thread exiting')
def move(self, forceNsp=False): if not self.path: Print.error('no path set') return False if os.path.abspath(self.path).startswith( os.path.abspath(Config.paths.nspOut) ) and not self.path.endswith('.nsz') and not self.path.endswith( '.xcz') and Config.compression.auto: nszFile = nut.compress(self.path, Config.compression.level, os.path.abspath(Config.paths.nspOut)) if nszFile: nsp = Fs.Nsp(nszFile, None) nsp.hasValidTicket = True nsp.move(forceNsp=True) Nsps.files[nsp.path] = nsp Nsps.save() newPath = self.fileName(forceNsp=forceNsp) if not newPath: Print.error('could not get filename for ' + self.path) return False if os.path.abspath(newPath).lower().replace( '\\', '/') == os.path.abspath(self.path).lower().replace('\\', '/'): return False if os.path.isfile(newPath): Print.info('\nduplicate title: ') Print.info(os.path.abspath(self.path)) Print.info(os.path.abspath(newPath)) Print.info('\n') return False if not self.verifyNcaHeaders(): Print.error('verification failed: could not move title for ' + str(self.titleId) + ' or ' + str(Title.getBaseId(self.titleId))) return False try: Print.info(self.path + ' -> ' + newPath) if not Config.dryRun: os.makedirs(os.path.dirname(newPath), exist_ok=True) #newPath = self.fileName(forceNsp = forceNsp) if not Config.dryRun: if self.isOpen(): self.close() shutil.move(self.path, newPath) if self.path in Nsps.files: del Nsps.files[self.path] Nsps.files[newPath] = self self.path = newPath except BaseException as e: Print.error('failed to rename file! %s -> %s : %s' % (self.path, newPath, e)) if not Config.dryRun: self.moveDupe() return True
nsp.verified = False raise IOError('bad file') nsp.verified = True Print.info('good file: ' + str(path)) bf.write('good file: %s\n' % str(path)) f.close() except: f.close() Print.error('bad file: ' + str(path)) bf.write('bad file: %s\n' % str(path)) s.add() s.close() Nsps.save() if args.verify_title_key: nut.initTitles() nut.initFiles() if blockchain.verifyKey(args.verify[0], args.verify[1]): Print.info('Title key is valid') else: Print.info('Title key is INVALID %s - %s' % (args.verify[0], args.verify[1])) if args.restore: nut.initTitles() nut.initFiles() prev = Config.extractVersion Config.extractVersion = True
def organize(): initTitles() initFiles() # scan() Print.info('organizing') # for k, f in Nsps.files.items(): #print('moving ' + f.path) #Print.info(str(f.hasValidTicket) +' = ' + f.path) # f.move() for id, t in Titles.data().items(): if not t.isActive(True): continue files = {} for f in t.getFiles(): ext = f.path[-4:] if ext not in files: files[ext] = [] files[ext].append(f) hasNsp = False if '.nsp' in files and len(files['.nsp']) > 0: latest = t.getLatestNsp() if latest: for f in files['.nsp']: if f.path != latest.path: f.moveDupe() hasNsp = True latest.move() if '.nsz' in files and len(files['.nsz']) > 0: latest = t.getLatestNsz() if latest: for f in files['.nsz']: if f.path != latest.path: f.moveDupe() hasNsp = True latest.move() if '.nsx' in files and len(files['.nsx']) > 0: latest = t.getLatestNsx() if latest: for f in files['.nsx']: if f.path != latest.path: f.moveDupe() if hasNsp: latest.moveDupe() else: latest.move() if '.xci' in files and len(files['.xci']) > 0: latest = t.getLatestXci() if latest: for f in files['.xci']: if f.path != latest.path: f.moveDupe() latest.move() Print.info('removing empty directories') Nsps.removeEmptyDir('.', False) Nsps.save()