def setup_workspace(self):
   umdimage  = os.path.join(self.iso_dir, UMDIMAGE_DAT)
   umdimage2 = os.path.join(self.iso_dir, UMDIMAGE2_DAT)
   voice     = os.path.join(self.iso_dir, VOICE_PAK)
   
   self.generate_directories()
   
   progress = QProgressDialog("", QtCore.QString(), 0, 11000, self)
   progress.setWindowTitle("Setting up workspace...")
   progress.setWindowModality(Qt.Qt.WindowModal)
   progress.setMinimumDuration(0)
   progress.setValue(0)
   progress.setAutoClose(False)
   progress.setAutoReset(False)
   
   progress.setLabelText("Creating directories...")
   
   # Do the easy stuff first.
   if not os.path.isdir(self.changes_dir):
     os.makedirs(self.changes_dir)
   progress.setValue(progress.value() + 1)
   
   if not os.path.isdir(self.backup_dir):
     os.makedirs(self.backup_dir)
   progress.setValue(progress.value() + 1)
   
   if not os.path.isdir(self.editor_data_dir):
     os.makedirs(self.editor_data_dir)
   progress.setValue(progress.value() + 1)
   
   thread_fns = [
     {"target": extract_umdimage, "kwargs": {"filename": umdimage,  "out_dir": self.umdimage_dir,  "eboot": self.eboot_path, "umdimage": UMDIMAGES.umdimage}},
     {"target": extract_umdimage, "kwargs": {"filename": umdimage2, "out_dir": self.umdimage2_dir, "eboot": self.eboot_path, "umdimage": UMDIMAGES.umdimage2}},
     {"target": extract_pak,      "kwargs": {"filename": voice,     "out_dir": self.voice_dir}},
   ]
   
   # Going to capture stdout because I don't feel like
   # rewriting the extract functions to play nice with GUI.
   stdout      = sys.stdout
   sys.stdout  = cStringIO.StringIO()
   
   for thread_fn in thread_fns:
     thread = threading.Thread(**thread_fn)
     thread.start()
     
     while thread.isAlive():
       thread.join(THREAD_TIMEOUT)
       
       output = [line for line in sys.stdout.getvalue().split('\n') if len(line) > 0]
       progress.setValue(progress.value() + len(output))
       if len(output) > 0:
         progress.setLabelText("Extracting %s..." % output[-1])
       
       sys.stdout = cStringIO.StringIO()
   
   sys.stdout = stdout
   
   # Give us an ISO directory for the editor to place modified files in.
   progress.setLabelText("Copying ISO files...")
   
   # ISO directory needs to not exist for copytree.
   if os.path.isdir(self.edited_iso_dir):
     shutil.rmtree(self.edited_iso_dir)
   
   # One more thing we want threaded so it doesn't lock up the GUI.
   thread = threading.Thread(target = shutil.copytree, kwargs = {"src": self.iso_dir, "dst": self.edited_iso_dir})
   thread.start()
   
   while thread.isAlive():
     thread.join(THREAD_TIMEOUT)
     progress.setLabelText("Copying ISO files...")
     # It has to increase by some amount or it won't update and the UI will lock up.
     progress.setValue(progress.value() + 1)
     
   # shutil.copytree(self.iso_dir, self.edited_iso_dir)
   progress.setValue(progress.value() + 1)
   
   # Files we want to make blank, because they're unnecessary.
   blank_files = [
     os.path.join(self.edited_iso_dir, "PSP_GAME", "INSDIR", "UMDIMAGE.DAT"),
     os.path.join(self.edited_iso_dir, "PSP_GAME", "SYSDIR", "UPDATE", "DATA.BIN"),
     os.path.join(self.edited_iso_dir, "PSP_GAME", "SYSDIR", "UPDATE", "EBOOT.BIN"),
     os.path.join(self.edited_iso_dir, "PSP_GAME", "SYSDIR", "UPDATE", "PARAM.SFO"),
   ]
   
   for blank in blank_files:
     with open(blank, "wb") as f:
       pass
   
   # Copy the decrypted EBOOT into the ISO folder and apply our hacks to it.
   progress.setLabelText("Hacking EBOOT...")
   progress.setValue(progress.value() + 1)
   
   hacked_eboot = BitStream(filename = self.eboot_path)
   hacked_eboot, offset = apply_eboot_patches(hacked_eboot)
   with open(os.path.join(self.edited_iso_dir, "PSP_GAME", "SYSDIR", "EBOOT.BIN"), "wb") as f:
     hacked_eboot.tofile(f)
   # shutil.copy(self.eboot_path, os.path.join(self.edited_iso_dir, "PSP_GAME", "SYSDIR", "EBOOT.BIN"))
   
   progress.setLabelText("Extracting editor data...")
   progress.setValue(progress.value() + 1)
   
   # Extract the editor data.
   editor_data = zipfile.ZipFile("data/editor_data.zip", "r")
   editor_data.extractall(self.editor_data_dir)
   editor_data.close()
   
   progress.setValue(progress.maximum())
   progress.close()
   
   self.ui.grpStep4.setEnabled(False)
   self.ui.grpStep5.setEnabled(True)
 def create_archives(self):
   
   try:
     self.width = self.parent.width()
     self.height = self.parent.height()
     self.x = self.parent.x()
     self.y = self.parent.y()
   except:
     self.width = 1920
     self.height = 1080
     self.x = 0
     self.y = 0
   
   self.progress = QProgressDialog("Reading...", QtCore.QString(), 0, 7600, self.parent)
   self.progress.setWindowModality(Qt.Qt.WindowModal)
   self.progress.setValue(0)
   self.progress.setAutoClose(False)
   self.progress.setMinimumDuration(0)
   
   USRDIR     = os.path.join(common.editor_config.iso_dir, "PSP_GAME", "USRDIR")
   eboot_path = os.path.join(common.editor_config.iso_dir, "PSP_GAME", "SYSDIR", "EBOOT.BIN")
   
   eboot = BitStream(filename = eboot_path)
   eboot = eboot_patch.apply_eboot_patches(eboot)
   
   # So we can loop. :)
   ARCHIVE_INFO = [
     {
       "dir":  common.editor_config.data00_dir,
       "cpk":  os.path.join(USRDIR, "data00.cpk"),
       "csv":  os.path.join("data", "data00.csv" if not common.editor_config.quick_build else "data00-quick.csv"),
       "name": "data00.cpk",
       "pack": common.editor_config.pack_data00,
     },
     {
       "dir":  common.editor_config.data01_dir,
       "cpk":  os.path.join(USRDIR, "data01.cpk"),
       "csv":  os.path.join("data", "data01.csv" if not common.editor_config.quick_build else "data01-quick.csv"),
       "name": "data01.cpk",
       "pack": common.editor_config.pack_data01,
     },
   ]
   
   # temp_dir = tempfile.mkdtemp(prefix = "sdse-")
   temp_dir = common.editor_config.build_cache
   
   for archive in ARCHIVE_INFO:
     
     if not archive["pack"]:
       continue
     
     self.progress.setWindowTitle("Building " + archive["name"])
     
     toc_info = {}
     file_list = None
     
     if archive["toc"]:
       file_list = []
       
       toc = get_toc(eboot, archive["toc"])
       
       for entry in toc:
         filename  = entry["filename"]
         pos_pos   = entry["file_pos_pos"]
         len_pos   = entry["file_len_pos"]
         
         toc_info[filename] = [pos_pos, len_pos]
         file_list.append(filename)
     
     # Causes memory issues if I use the original order, for whatever reason.
     file_list = None
     
     csv_template_f  = open(archive["csv"], "rb")
     csv_template    = csv.reader(csv_template_f)
     
     csv_out_path    = os.path.join(temp_dir, "cpk.csv")
     csv_out_f       = open(csv_out_path, "wb")
     csv_out         = csv.writer(csv_out_f)
     
     for row in csv_template:
       if len(row) < 4:
         continue
       
       base_path = row[0]
       
       real_path = os.path.join(archive["dir"], base_path)
       out_path  = os.path.join(temp_dir, archive["name"], base_path)
       
       self.progress.setValue(self.progress.value() + 1)
       self.progress.setLabelText("Reading...\n%s" % real_path)
       
       # All items in the CPK list should be files.
       # Therefore, if we have a directory, then it needs to be packed.
       if os.path.isdir(real_path):
         if self.__cache_outdated(real_path, out_path):
           out_dir = os.path.dirname(out_path)
           try:
             os.makedirs(out_dir)
           except:
             pass
           
           data = pack_dir(real_path)
           with open(out_path, "wb") as out_file:
             data.tofile(out_file)
           del data
           
       elif os.path.isfile(real_path):
       # If it's a file, though, we can just use it directly.
         out_path = real_path
         
       row[0] = out_path
       csv_out.writerow(row)
     
     csv_template_f.close()
     csv_out_f.close()
     
     self.__pack_cpk(csv_out_path, archive["cpk"])
     
     # We're playing fast and loose with the file count anyway, so why not?
     self.file_count += 1
     self.progress.setValue(self.file_count)
     self.progress.setLabelText("Saving " + archive["name"] + "...")
     
     if archive["toc"]:
       for entry in table_of_contents:
         if not entry in toc_info:
           _LOGGER.warning("%s missing from %s table of contents." % (entry, archive["name"]))
           continue
         
         file_pos  = table_of_contents[entry]["pos"]
         file_size = table_of_contents[entry]["size"]
         
         eboot.overwrite(BitStream(uintle = file_pos, length = 32),  toc_info[entry][0] * 8)
         eboot.overwrite(BitStream(uintle = file_size, length = 32), toc_info[entry][1] * 8)
     
     del table_of_contents
   
   self.progress.setWindowTitle("Building...")
   self.progress.setLabelText("Saving EBOOT.BIN...")
   self.progress.setValue(self.progress.maximum())
   
   with open(eboot_path, "wb") as f:
     eboot.tofile(f)
     
   # Text replacement
   to_replace = eboot_text.get_eboot_text()
   for replacement in to_replace:
   
     orig = bytearray(replacement.orig, encoding = replacement.enc)
     
     # If they left something blank, write the original text back.
     if len(replacement.text) == 0:
       data = orig
     else:
       data = bytearray(replacement.text, encoding = replacement.enc)
     
     pos  = replacement.pos.int + eboot_offset
     
     padding = len(orig) - len(data)
     if padding > 0:
       # Null bytes to fill the rest of the space the original took.
       data.extend(bytearray(padding))
     
     data = ConstBitStream(bytes = data)
     eboot.overwrite(data, pos * 8)
   
   eboot_out = os.path.join(common.editor_config.iso_dir, "PSP_GAME", "SYSDIR", "EBOOT.BIN")
   
   with open(eboot_out, "wb") as f:
     eboot.tofile(f)
   
   self.progress.close()
    def setup_workspace(self):
        data0 = os.path.join(self.iso_dir, DATA0_CPK)

        self.generate_directories()

        progress = QProgressDialog("", QtCore.QString(), 0, 11000, self)
        progress.setWindowTitle("Setting up workspace...")
        progress.setWindowModality(Qt.Qt.WindowModal)
        progress.setMinimumDuration(0)
        progress.setValue(0)
        progress.setAutoClose(False)
        progress.setAutoReset(False)

        progress.setLabelText("Creating directories...")

        # Do the easy stuff first.
        if not os.path.isdir(self.changes_dir):
            os.makedirs(self.changes_dir)
        progress.setValue(progress.value() + 1)

        if not os.path.isdir(self.backup_dir):
            os.makedirs(self.backup_dir)
        progress.setValue(progress.value() + 1)

        thread_fns = [{"target": extract_cpk, "kwargs": {"filename": data0, "out_dir": self.data0_dir}}]

        # Going to capture stdout because I don't feel like
        # rewriting the extract functions to play nice with GUI.
        stdout = sys.stdout
        sys.stdout = cStringIO.StringIO()

        for thread_fn in thread_fns:
            thread = threading.Thread(**thread_fn)
            thread.start()

            while thread.isAlive():
                thread.join(THREAD_TIMEOUT)

                output = [line for line in sys.stdout.getvalue().split("\n") if len(line) > 0]
                progress.setValue(progress.value() + len(output))
                if len(output) > 0:
                    progress.setLabelText("Extracting %s..." % output[-1])

                sys.stdout = cStringIO.StringIO()

        sys.stdout = stdout

        # Give us an ISO directory for the editor to place modified files in.
        progress.setLabelText("Copying ISO files...")

        # ISO directory needs to not exist for copytree.
        if os.path.isdir(self.edited_iso_dir):
            shutil.rmtree(self.edited_iso_dir)

        # One more thing we want threaded so it doesn't lock up the GUI.
        thread = threading.Thread(target=shutil.copytree, kwargs={"src": self.iso_dir, "dst": self.edited_iso_dir})
        thread.start()

        while thread.isAlive():
            thread.join(THREAD_TIMEOUT)
            progress.setLabelText("Copying ISO files...")
            # It has to increase by some amount or it won't update and the UI will lock up.
            progress.setValue(progress.value() + 1)

        # shutil.copytree(self.iso_dir, self.edited_iso_dir)
        progress.setValue(progress.value() + 1)

        # Files we want to make blank, because they're unnecessary.
        blank_files = [
            os.path.join(self.edited_iso_dir, "PSP_GAME", "SYSDIR", "UPDATE", "DATA.BIN"),
            os.path.join(self.edited_iso_dir, "PSP_GAME", "SYSDIR", "UPDATE", "EBOOT.BIN"),
            os.path.join(self.edited_iso_dir, "PSP_GAME", "SYSDIR", "UPDATE", "PARAM.SFO"),
        ]

        for blank in blank_files:
            with open(blank, "wb") as f:
                pass

        # Copy the decrypted EBOOT into the ISO folder and apply our hacks to it.
        progress.setLabelText("Hacking EBOOT...")
        progress.setValue(progress.value() + 1)

        hacked_eboot = BitStream(filename=self.eboot_path)
        hacked_eboot = apply_eboot_patches(hacked_eboot)
        with open(os.path.join(self.edited_iso_dir, "PSP_GAME", "SYSDIR", "EBOOT.BIN"), "wb") as f:
            hacked_eboot.tofile(f)
        # shutil.copy(self.eboot_path, os.path.join(self.edited_iso_dir, "PSP_GAME", "SYSDIR", "EBOOT.BIN"))

        progress.setLabelText("Extracting editor data...")
        progress.setValue(progress.value() + 1)

        # Extract the editor data.
        editor_data = zipfile.ZipFile("data/editor_data.zip", "r")
        editor_data.extractall(self.editor_data_dir)
        editor_data.close()

        progress.setValue(progress.maximum())
        progress.close()

        self.ui.grpStep4.setEnabled(False)
        self.ui.grpStep5.setEnabled(True)
    def create_archives(self):

        try:
            self.width = self.parent.width()
            self.height = self.parent.height()
            self.x = self.parent.x()
            self.y = self.parent.y()
        except:
            self.width = 1920
            self.height = 1080
            self.x = 0
            self.y = 0

        self.file_count = 0

        self.progress = QProgressDialog("Reading...", QtCore.QString(), 0,
                                        72000, self.parent)
        self.progress.setWindowModality(Qt.Qt.WindowModal)
        self.progress.setValue(0)
        self.progress.setAutoClose(False)
        self.progress.setMinimumDuration(0)

        # with open(common.editor_config.eboot_orig, "rb") as f:
        with open(
                os.path.join(common.editor_config.iso_dir, "PSP_GAME",
                             "SYSDIR", "EBOOT.BIN"), "rb") as f:
            eboot = BitStream(bytes=f.read())

        eboot, eboot_offset = eboot_patch.apply_eboot_patches(eboot)

        USRDIR = os.path.join(common.editor_config.iso_dir, "PSP_GAME",
                              "USRDIR")

        # So we can loop. :)
        ARCHIVE_INFO = [
            {
                "toc": UMDIMAGES.umdimage,
                "dir": common.editor_config.umdimage_dir,
                "dat": os.path.join(USRDIR, "umdimage.dat"),
                "name": "umdimage.dat",
                "pack": common.editor_config.pack_umdimage,
                "eof": False,
            },
            {
                "toc": UMDIMAGES.umdimage2,
                "dir": common.editor_config.umdimage2_dir,
                "dat": os.path.join(USRDIR, "umdimage2.dat"),
                "name": "umdimage2.dat",
                "pack": common.editor_config.pack_umdimage2,
                "eof": False,
            },
            {
                "toc": None,
                "dir": common.editor_config.voice_dir,
                "dat": os.path.join(USRDIR, "voice.pak"),
                "name": "voice.pak",
                "pack": common.editor_config.pack_voice,
                "eof": True,
            },
            {
                "toc": None,
                "dir": common.editor_config.bgm_dir,
                "dat": os.path.join(USRDIR, "bgm.pak"),
                "name": "bgm.pak",
                "pack": common.editor_config.pack_bgm,
                "eof": True,
            },
        ]

        for archive in ARCHIVE_INFO:

            if not archive["pack"]:
                continue

            self.progress.setWindowTitle("Building " + archive["name"])

            toc_info = {}
            file_list = None

            if archive["toc"]:
                file_list = []

                toc = get_toc(eboot, archive["toc"])

                for entry in toc:
                    filename = entry["filename"]
                    pos_pos = entry["file_pos_pos"]
                    len_pos = entry["file_len_pos"]

                    toc_info[filename] = [pos_pos, len_pos]
                    file_list.append(filename)

            # Causes memory issues if I use the original order, for whatever reason.
            file_list = None

            with io.FileIO(archive["dat"], "w") as handler:
                table_of_contents = self.pack_dir(archive["dir"],
                                                  handler,
                                                  file_list=file_list,
                                                  eof=archive["eof"])

            # We're playing fast and loose with the file count anyway, so why not?
            self.file_count += 1
            self.progress.setValue(self.file_count)
            self.progress.setLabelText("Saving " + archive["name"] + "...")

            if archive["toc"]:
                for entry in table_of_contents:
                    if not entry in toc_info:
                        _LOGGER.warning(
                            "%s missing from %s table of contents." %
                            (entry, archive["name"]))
                        continue

                    file_pos = table_of_contents[entry]["pos"]
                    file_size = table_of_contents[entry]["size"]

                    eboot.overwrite(BitStream(uintle=file_pos, length=32),
                                    toc_info[entry][0] * 8)
                    eboot.overwrite(BitStream(uintle=file_size, length=32),
                                    toc_info[entry][1] * 8)

            del table_of_contents

        self.progress.setLabelText("Saving EBOOT.BIN...")
        self.progress.setValue(self.progress.maximum())

        # Text replacement
        to_replace = eboot_text.get_eboot_text()
        for replacement in to_replace:

            orig = bytearray(replacement.orig, encoding=replacement.enc)

            # If they left something blank, write the original text back.
            if len(replacement.text) == 0:
                data = orig
            else:
                data = bytearray(replacement.text, encoding=replacement.enc)

            pos = replacement.pos.int + eboot_offset

            padding = len(orig) - len(data)
            if padding > 0:
                # Null bytes to fill the rest of the space the original took.
                data.extend(bytearray(padding))

            data = ConstBitStream(bytes=data)
            eboot.overwrite(data, pos * 8)

        eboot_out = os.path.join(common.editor_config.iso_dir, "PSP_GAME",
                                 "SYSDIR", "EBOOT.BIN")

        with open(eboot_out, "wb") as f:
            eboot.tofile(f)

        self.progress.close()
 def create_archives(self):
   
   try:
     self.width = self.parent.width()
     self.height = self.parent.height()
     self.x = self.parent.x()
     self.y = self.parent.y()
   except:
     self.width = 1920
     self.height = 1080
     self.x = 0
     self.y = 0
   
   self.progress = QProgressDialog("Reading...", QtCore.QString(), 0, 7600, self.parent)
   self.progress.setWindowModality(Qt.Qt.WindowModal)
   self.progress.setValue(0)
   self.progress.setAutoClose(False)
   self.progress.setMinimumDuration(0)
   
   USRDIR     = os.path.join(common.editor_config.iso_dir, "PSP_GAME", "USRDIR")
   eboot_path = os.path.join(common.editor_config.iso_dir, "PSP_GAME", "SYSDIR", "EBOOT.BIN")
   
   eboot = BitStream(filename = eboot_path)
   eboot = eboot_patch.apply_eboot_patches(eboot)
   
   # So we can loop. :)
   ARCHIVE_INFO = [
     {
       "dir":  common.editor_config.data00_dir,
       "cpk":  os.path.join(USRDIR, "data00.cpk"),
       "csv":  os.path.join("data", "data00.csv" if not common.editor_config.quick_build else "data00-quick.csv"),
       "name": "data00.cpk",
       "pack": common.editor_config.pack_data00,
     },
     {
       "dir":  common.editor_config.data01_dir,
       "cpk":  os.path.join(USRDIR, "data01.cpk"),
       "csv":  os.path.join("data", "data01.csv" if not common.editor_config.quick_build else "data01-quick.csv"),
       "name": "data01.cpk",
       "pack": common.editor_config.pack_data01,
     },
   ]
   
   # temp_dir = tempfile.mkdtemp(prefix = "sdse-")
   temp_dir = common.editor_config.build_cache
   
   for archive in ARCHIVE_INFO:
     
     if not archive["pack"]:
       continue
     
     self.progress.setWindowTitle("Building " + archive["name"])
     
     csv_template_f  = open(archive["csv"], "rb")
     csv_template    = csv.reader(csv_template_f)
     
     csv_out_path    = os.path.join(temp_dir, "cpk.csv")
     csv_out_f       = open(csv_out_path, "wb")
     csv_out         = csv.writer(csv_out_f)
     
     for row in csv_template:
       if len(row) < 4:
         continue
       
       base_path = row[0]
       
       real_path = os.path.join(archive["dir"], base_path)
       out_path  = os.path.join(temp_dir, archive["name"], base_path)
       
       self.progress.setValue(self.progress.value() + 1)
       self.progress.setLabelText("Reading...\n%s" % real_path)
       
       # All items in the CPK list should be files.
       # Therefore, if we have a directory, then it needs to be packed.
       if os.path.isdir(real_path):
         if self.__cache_outdated(real_path, out_path):
           out_dir = os.path.dirname(out_path)
           try:
             os.makedirs(out_dir)
           except:
             pass
           
           data = pack_dir(real_path)
           with open(out_path, "wb") as out_file:
             data.tofile(out_file)
           del data
           
       elif os.path.isfile(real_path):
         # If it's a file, though, we can just use it directly.
         out_path = real_path
         
       row[0] = out_path
       csv_out.writerow(row)
     
     csv_template_f.close()
     csv_out_f.close()
     
     self.__pack_cpk(csv_out_path, archive["cpk"])
   
   self.progress.setWindowTitle("Building...")
   self.progress.setLabelText("Saving EBOOT.BIN...")
   self.progress.setValue(self.progress.maximum())
   
   with open(eboot_path, "wb") as f:
     eboot.tofile(f)
   
   # self.progress.setLabelText("Deleting temporary files...")
   # shutil.rmtree(temp_dir)
   self.progress.close()
    def create_archives(self):

        try:
            self.width = self.parent.width()
            self.height = self.parent.height()
            self.x = self.parent.x()
            self.y = self.parent.y()
        except:
            self.width = 1920
            self.height = 1080
            self.x = 0
            self.y = 0

        self.progress = QProgressDialog("Reading...", QtCore.QString(), 0,
                                        7600, self.parent)
        self.progress.setWindowModality(Qt.Qt.WindowModal)
        self.progress.setValue(0)
        self.progress.setAutoClose(False)
        self.progress.setMinimumDuration(0)

        USRDIR = os.path.join(common.editor_config.iso_dir, "PSP_GAME",
                              "USRDIR")
        eboot_path = os.path.join(common.editor_config.iso_dir, "PSP_GAME",
                                  "SYSDIR", "EBOOT.BIN")

        eboot = BitStream(filename=eboot_path)
        eboot = eboot_patch.apply_eboot_patches(eboot)

        # So we can loop. :)
        ARCHIVE_INFO = [
            {
                "dir":
                common.editor_config.data00_dir,
                "cpk":
                os.path.join(USRDIR, "data00.cpk"),
                "csv":
                os.path.join(
                    "data",
                    "data00.csv" if not common.editor_config.quick_build else
                    "data00-quick.csv"),
                "name":
                "data00.cpk",
                "pack":
                common.editor_config.pack_data00,
            },
            {
                "dir":
                common.editor_config.data01_dir,
                "cpk":
                os.path.join(USRDIR, "data01.cpk"),
                "csv":
                os.path.join(
                    "data",
                    "data01.csv" if not common.editor_config.quick_build else
                    "data01-quick.csv"),
                "name":
                "data01.cpk",
                "pack":
                common.editor_config.pack_data01,
            },
        ]

        # temp_dir = tempfile.mkdtemp(prefix = "sdse-")
        temp_dir = common.editor_config.build_cache

        for archive in ARCHIVE_INFO:

            if not archive["pack"]:
                continue

            self.progress.setWindowTitle("Building " + archive["name"])

            csv_template_f = open(archive["csv"], "rb")
            csv_template = csv.reader(csv_template_f)

            csv_out_path = os.path.join(temp_dir, "cpk.csv")
            csv_out_f = open(csv_out_path, "wb")
            csv_out = csv.writer(csv_out_f)

            for row in csv_template:
                if len(row) < 4:
                    continue

                base_path = row[0]

                real_path = os.path.join(archive["dir"], base_path)
                out_path = os.path.join(temp_dir, archive["name"], base_path)

                self.progress.setValue(self.progress.value() + 1)
                self.progress.setLabelText("Reading...\n%s" % real_path)

                # All items in the CPK list should be files.
                # Therefore, if we have a directory, then it needs to be packed.
                if os.path.isdir(real_path):
                    if self.__cache_outdated(real_path, out_path):
                        out_dir = os.path.dirname(out_path)
                        try:
                            os.makedirs(out_dir)
                        except:
                            pass

                        data = pack_dir(real_path)
                        with open(out_path, "wb") as out_file:
                            data.tofile(out_file)
                        del data

                elif os.path.isfile(real_path):
                    # If it's a file, though, we can just use it directly.
                    out_path = real_path

                row[0] = out_path
                csv_out.writerow(row)

            csv_template_f.close()
            csv_out_f.close()

            self.__pack_cpk(csv_out_path, archive["cpk"])

        self.progress.setWindowTitle("Building...")
        self.progress.setLabelText("Saving EBOOT.BIN...")
        self.progress.setValue(self.progress.maximum())

        with open(eboot_path, "wb") as f:
            eboot.tofile(f)

        # self.progress.setLabelText("Deleting temporary files...")
        # shutil.rmtree(temp_dir)
        self.progress.close()