Ejemplo n.º 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
Ejemplo n.º 2
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))
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
    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