コード例 #1
0
    def fileName(self):
        bt = None
        if not self.titleId in Titles.keys():
            if not Title.getBaseId(self.titleId) in Titles.keys():
                Print.info('could not find title key for ' +
                           str(self.titleId) + ' or ' +
                           str(Title.getBaseId(self.titleId)))
                return None
            bt = Titles.get(Title.getBaseId(self.titleId))
            t = Title()
            t.loadCsv(self.titleId + '0000000000000000|0000000000000000|' +
                      bt.name)
        else:
            t = Titles.get(self.titleId)

            if not t:
                Print.error('could not find title id ' + str(self.titleId))
                return None

            try:
                if not t.baseId in Titles.keys():
                    Print.info('could not find baseId for ' + self.path)
                    return None
            except BaseException as e:
                print('exception: could not find title id ' +
                      str(self.titleId) + ' ' + str(e))
                return None
            bt = Titles.get(t.baseId)

        if t.isDLC:
            format = Config.paths.getTitleDLC(not self.hasValidTicket)
        elif t.isDemo:
            if t.idExt != 0:
                format = Config.paths.getTitleDemoUpdate(
                    not self.hasValidTicket)
            else:
                format = Config.paths.getTitleDemo(not self.hasValidTicket)
        elif t.idExt != 0:
            format = Config.paths.getTitleUpdate(not self.hasValidTicket)
        else:
            format = Config.paths.getTitleBase(not self.hasValidTicket)

        format = format.replace('{id}', self.cleanFilename(t.id))
        format = format.replace('{region}',
                                self.cleanFilename(t.getRegion() or ''))
        format = format.replace('{name}', self.cleanFilename(t.getName()
                                                             or ''))
        format = format.replace('{version}', str(self.getVersion() or 0))
        format = format.replace('{baseId}', self.cleanFilename(bt.id))

        baseName = self.cleanFilename(bt.getName() or '')
        result = format.replace('{baseName}', baseName)

        while (len(os.path.basename(result).encode('utf-8')) > 240
               and len(baseName) > 3):
            baseName = baseName[:-1]
            result = format.replace('{baseName}', baseName)

        return result
コード例 #2
0
ファイル: __init__.py プロジェクト: blawar/nut
def updateVersions(force=True):
	initTitles()
	initFiles()

	i = 0
	for k, t in Titles.items():
		if force or t.version is None:
			if (t.isDLC or t.isUpdate or Config.download.base) and (not t.isDLC or Config.download.DLC) and (not t.isDemo or Config.download.demo) and (not t.isUpdate or Config.download.update) and (
					t.key or Config.download.sansTitleKey) and (len(Config.titleWhitelist) == 0 or t.id in Config.titleWhitelist) and t.id not in Config.titleBlacklist:
				v = t.lastestVersion(True)
				Print.info("%s[%s] v = %s" % (str(t.name), str(t.id), str(v)))

				i = i + 1
				if i % 20 == 0:
					Titles.save()

	for t in list(Titles.data().values()):
		if not t.isUpdate and not t.isDLC and t.updateId and t.updateId and not Titles.contains(t.updateId):
			u = Title.Title()
			u.setId(t.updateId)

			if u.lastestVersion():
				Titles.set(t.updateId, u)

				Print.info("%s[%s] FOUND" % (str(t.name), str(u.id)))

				i = i + 1
				if i % 20 == 0:
					Titles.save()

	Titles.save()
コード例 #3
0
ファイル: Titles.py プロジェクト: zdm65477730/nut
def load():
	confLock.acquire()
	global titles
	titles = {}

	if os.path.isfile("titledb/titles.json"):
		timestamp = time.clock()
		with open('titledb/titles.json', encoding="utf-8-sig") as f:
			for i, k in json.loads(f.read()).items():
				titles[i] = Title.Title()
				titles[i].__dict__ = k
				titles[i].setId(i)

		Print.info('loaded titledb/titles.json in ' + str(time.clock() - timestamp) + ' seconds')

		'''
	if os.path.isfile("titles.txt"):
		loadTitleFile('titles.txt', True)

	try:
		files = [f for f in os.listdir(Config.paths.titleDatabase) if f.endswith('.txt')]
		files.sort()
	
		for file in files:
			loadTitleFile(Config.paths.titleDatabase + '/' + file, False)
	except BaseException as e:
		Print.error('title load error: ' + str(e))
		'''
	confLock.release()
コード例 #4
0
ファイル: Titles.py プロジェクト: zdm65477730/nut
def get(key, region = None, language = None):
	key = key.upper()

	if not key in data(region, language):
		t = Title.Title()
		t.setId(key)
		data(region, language)[key] = t
	return data(region, language)[key]
コード例 #5
0
def scanDLC(id, showErr=True, dlcStatus=None):
    id = id.upper()
    title = Titles.get(id)
    baseDlc = Title.baseDlcId(id)
    for i in range(0x1FF):
        scanId = format(baseDlc + i, 'X').zfill(16)
        if Titles.contains(scanId):
            continue
        ver = CDNSP.get_version(scanId.lower())
        if ver != None:
            t = Title()
            t.setId(scanId)
            Titles.set(scanId, t)
            Titles.save()
            Print.info('Found new DLC ' + str(title.name) + ' : ' + scanId)
        elif showErr:
            Print.info('nothing found at ' + scanId + ', ' + str(ver))
        if dlcStatus:
            dlcStatus.add()
コード例 #6
0
ファイル: IndexedFile.py プロジェクト: yukun451/nut
    def title(self):
        if not self.titleId:
            raise IOError('NSP no titleId set')

        if self.titleId in Titles.keys():
            return Titles.get(self.titleId)

        t = Title.Title()
        t.setId(self.titleId)
        Titles.data()[self.titleId] = t
        return t
コード例 #7
0
def scanBaseThread(baseStatus):
    while Config.isRunning:
        try:
            id = getRandomTitleId()

            if Titles.contains(id):
                continue

            ver = CDNSP.get_version(id.lower())

            if ver != None:
                Print.info('Found new base ' + id)
                t = Title()
                t.setId(id)
                Titles.set(id, t)
                Titles.save()

            baseStatus.add()
        except BaseException as e:
            print('exception: ' + str(e))
コード例 #8
0
def scanLatestTitleUpdates():
    nut.initTitles()
    nut.initFiles()

    for k, i in CDNSP.get_versionUpdates().items():
        id = str(k).upper()
        version = str(i)

        if not Titles.contains(id):
            if len(id) != 16:
                Print.info('invalid title id: ' + id)
                continue
            continue
            t = Title()
            t.setId(id)
            Titles.set(id, t)
            Print.info('Found new title id: ' + str(id))

        t = Titles.get(id)
        if str(t.version) != str(version):
            Print.info('new version detected for %s[%s] v%s' %
                       (t.name or '', t.id or ('0' * 16), str(version)))
            t.setVersion(version, True)

    Titles.save()
コード例 #9
0
ファイル: Titles.py プロジェクト: zdm65477730/nut
def getNsuid(id, region, language):
	id = int(id)

	map = data(region, language)

	for t in map:
		if map[t].nsuId == id:
			return map[t]

	title = Title.Title()
	title.setNsuId(id)

	map[str(id)] = title
	return title
コード例 #10
0
ファイル: Titles.py プロジェクト: zdm65477730/nut
def loadTitlesJson(filePath = 'titledb/titles.json'):
	newTitles = {}
	confLock.acquire()
	if os.path.isfile(filePath):
		timestamp = time.clock()
		with open(filePath, encoding="utf-8-sig") as f:
			for i, k in json.loads(f.read()).items():
				newTitles[i] = Title.Title()
				newTitles[i].__dict__ = k
				newTitles[i].setId(i)

		Print.info('loaded ' + filePath + ' in ' + str(time.clock() - timestamp) + ' seconds')

	confLock.release()
	return newTitles
コード例 #11
0
def scanLatestTitleUpdates():
    global versionHistory
    initTitles()
    initFiles()

    now = datetime.datetime.now()
    today = now.strftime("%Y-%m-%d")

    try:
        with open('titledb/versions.json', 'r') as f:
            for titleId, vers in json.loads(f.read()).items():
                for ver, date in vers.items():
                    setVersionHistory(titleId, ver, date)
    except BaseException:
        pass

    if not hasCdn:
        return

    for k, i in cdn.hacVersionList().items():
        id = str(k).upper()
        version = str(i)

        if not Titles.contains(id):
            if len(id) != 16:
                Print.info('invalid title id: ' + id)
                continue

        t = Titles.get(id)

        if t.isUpdate:
            setVersionHistory(Title.getBaseId(id), version, today)
        else:
            setVersionHistory(id, version, today)

        if str(t.version) != str(version):
            Print.info('new version detected for %s[%s] v%s' %
                       (t.name or '', t.id or ('0' * 16), str(version)))
            t.setVersion(version, True)

    Titles.save()

    try:
        with open('titledb/versions.json', 'w') as outfile:
            json.dump(versionHistory, outfile, indent=4, sort_keys=True)
    except BaseException as e:
        Print.info(str(e))
コード例 #12
0
def loadTitlesJson(filePath = 'titledb/titles.json'):
	newTitles = {}
	confLock.acquire()
	try:
		if os.path.isfile(filePath):
			timestamp = time.process_time()
			with open(filePath, encoding="utf-8-sig") as f:
				for i, k in json.loads(f.read()).items():
					newTitles[i] = Title.Title()
					newTitles[i].__dict__ = k
					newTitles[i].setId(i)

			Print.info('loaded ' + filePath + ' in ' + str(time.process_time() - timestamp) + ' seconds')
	except BaseException as e:
		print("load titles json exception: " + str(e))

	confLock.release()
	return newTitles
コード例 #13
0
def loadTitleBuffer(buffer, silent=False):
    global nsuIdMap
    firstLine = True
    importedRegions = {}
    map = ['id', 'key', 'name']
    for line in buffer.split('\n'):
        line = line.strip()
        if len(line) == 0 or line[0] == '#':
            continue
        if firstLine:
            firstLine = False
            if re.match('[A-Za-z\|\s]+', line, re.I):
                map = line.split('|')

                i = 0
                while i < len(map):
                    if map[i] == 'RightsID':
                        map[i] = 'id'
                    if map[i] == 'TitleKey':
                        map[i] = 'key'
                    if map[i] == 'Name':
                        map[i] = 'name'
                    i += 1
                continue

        t = Title.Title()
        t.loadCsv(line, map)

        if not isinstance(t.id, str):
            continue

        if 'nsuId' in map:
            nsuIdMap[t.nsuId] = t.id

        title = get(t.id, None, None)

        titleKey = title.key
        title.loadCsv(line, map)

        if not silent and titleKey != titles[t.id].key:
            Print.info('Added new title key for ' + str(titles[t.id].name) +
                       '[' + str(t.id) + ']')
コード例 #14
0
def updateVersions(force=True):
    initTitles()
    initFiles()

    i = 0
    for k, t in tqdm(Titles.items()):
        if force or t.version is None:
            if t.isActive():
                v = t.lastestVersion(True)
                Print.info("%s[%s] v = %s" % (str(t.name), str(t.id), str(v)))

    for t in list(Titles.data().values()):
        if not t.isUpdate and not t.isDLC and t.updateId and t.updateId and not Titles.contains(
                t.updateId):
            u = Title.Title()
            u.setId(t.updateId)

            if u.lastestVersion():
                Titles.set(t.updateId, u)

                Print.info("%s[%s] FOUND" % (str(t.name), str(u.id)))

    Titles.save()
コード例 #15
0
ファイル: IndexedFile.py プロジェクト: yukun451/nut
    def fileName(self, forceNsp=False):
        bt = None

        if self.titleId not in Titles.keys():
            if not Title.getBaseId(self.titleId) in Titles.keys():
                Print.error('could not find base title for ' +
                            str(self.titleId) + ' or ' +
                            str(Title.getBaseId(self.titleId)))
                return None
            bt = Titles.get(Title.getBaseId(self.titleId))
            t = Title.Title()
            if bt.name is not None:
                t.loadCsv(self.titleId + '0000000000000000|0000000000000000|' +
                          bt.name)
            else:
                t.setId(self.titleId)
        else:
            t = Titles.get(self.titleId)

            if not t:
                Print.error('could not find title id ' + str(self.titleId))
                return None

            try:
                if t.baseId not in Titles.keys():
                    Print.info('could not find baseId for ' + self.path)
                    return None
            except BaseException as e:
                Print.error('exception: could not find title id ' +
                            str(self.titleId) + ' ' + str(e))
                return None
            bt = Titles.get(t.baseId)

        isNsx = not self.hasValidTicket and not forceNsp

        try:
            if t.isDLC:
                format = Config.paths.getTitleDLC(isNsx, self.path)
            elif t.isDemo:
                if t.idExt != 0:
                    format = Config.paths.getTitleDemoUpdate(isNsx, self.path)
                else:
                    format = Config.paths.getTitleDemo(isNsx, self.path)
            elif t.idExt != 0:
                if bt and bt.isDemo:
                    format = Config.paths.getTitleDemoUpdate(isNsx, self.path)
                else:
                    format = Config.paths.getTitleUpdate(isNsx, self.path)
            else:
                format = Config.paths.getTitleBase(isNsx, self.path)
        except BaseException as e:
            Print.error('calc path exception: ' + str(e))
            return None

        if not format:
            return None

        newName = self.cleanFilename(t.getName() or '')

        format = format.replace('{id}', self.cleanFilename(t.id))
        format = format.replace(
            '{region}', self.cleanFilename(t.getRegion() or bt.getRegion()))
        format = format.replace('{name}', newName)
        format = format.replace('{version}', str(self.getVersion() or 0))
        format = format.replace('{baseId}', self.cleanFilename(bt.id))

        if '{cr}' in format:
            format = format.replace('{cr}', str(self.getCr()))

        if '{icr}' in format:
            format = format.replace('{icr}', str(self.getCr(True)))

        bn = os.path.basename(self.path)
        if (not newName or len(newName)
                == 0) and not bn.upper().startswith(t.id.upper()):
            Print.error('could not get new name for ' + bn)
            return os.path.join(os.path.dirname(format),
                                os.path.basename(self.path))

        baseName = self.cleanFilename(bt.getName() or '')

        if not baseName or len(baseName) == 0:
            baseName = os.path.basename(self.path)

        result = format.replace('{baseName}', baseName)

        while (len(os.path.basename(result).encode('utf-8')) > 240
               and len(baseName) > 3):
            baseName = baseName[:-1]
            result = format.replace('{baseName}', baseName)

        return os.path.abspath(result)
コード例 #16
0
ファイル: IndexedFile.py プロジェクト: yukun451/nut
    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