def set_folders(self, folder1, folder2, files=None):
        if files == None:
            files1 = list_all_files(folder1)
            files2 = list_all_files(folder2)

            files = set()

            # Get rid of our folder paths so we're working on generic filenames
            # that can be used with either folder.
            files.update([
                file[len(folder1) + 1:] for file in files1
                if file[-4:] == ".txt"
            ])
            files.update([
                file[len(folder2) + 1:] for file in files2
                if file[-4:] == ".txt"
            ])

        self.ui.lblDir1.setText(folder1)
        self.ui.lblDir2.setText(folder2)

        self.folder1 = folder1
        self.folder2 = folder2
        self.files = set(files)
        self.files_nodupes = None
        self.files_missing = None

        self.saved_diffs = {}

        self.show_files()
    def load(self, umdimage):
        dir = os.path.join(umdimage, "18_mapname.pak")

        self.map_names.clear()

        try:
            files = list_all_files(dir)
        except:
            return

        for file in files:
            name = os.path.basename(file)
            index = int(os.path.splitext(name)[0])

            script = ScriptFile(file)

            room_name = script.translated
            if room_name == "":
                room_name = script.original

            if room_name == u"※" or room_name == "":
                continue

            self.map_names[index] = room_name
            self.untranslated[index] = script.original
 def list_txt_files(dir_filter = DEFAULT_FILTER):
 
   # For our dupe database, we need the relative location of our files, not absolute.
   dir_start = len(common.editor_config.data01_dir) + 1
   
   for dir in ScriptAnalytics.list_dirs(dir_filter):
     dir_files = list_files.list_all_files(os.path.join(common.editor_config.data01_dir, SCRIPT_DIR, dir))
     for file in dir_files:
       if os.path.splitext(file)[1].lower() == ".txt":
         yield file[dir_start:]
 def __cache_outdated(self, src_dir, cache_file):
   if not os.path.isfile(cache_file):
     return True
   
   cache_updated = os.path.getmtime(cache_file)
   
   for src_file in list_all_files(src_dir):
     if os.path.getmtime(src_file) > cache_updated:
       return True
   
   return False
    def __cache_outdated(self, src_dir, cache_file):
        if not os.path.isfile(cache_file):
            return True

        cache_updated = os.path.getmtime(cache_file)

        for src_file in list_all_files(src_dir):
            if os.path.getmtime(src_file) > cache_updated:
                return True

        return False
    def list_txt_files(dir_filter=DEFAULT_FILTER):

        # For our dupe database, we need the relative location of our files, not absolute.
        dir_start = len(common.editor_config.data01_dir) + 1

        for dir in ScriptAnalytics.list_dirs(dir_filter):
            dir_files = list_files.list_all_files(
                os.path.join(common.editor_config.data01_dir, SCRIPT_DIR, dir))
            for file in dir_files:
                if os.path.splitext(file)[1].lower() == ".txt":
                    yield file[dir_start:]
 def set_folders(self, folder1, folder2, files = None):
   if files == None:
     files1 = list_all_files(folder1)
     files2 = list_all_files(folder2)
     
     files = set()
     
     # Get rid of our folder paths so we're working on generic filenames
     # that can be used with either folder.
     files.update([file[len(folder1) + 1:] for file in files1 if file[-4:] == ".txt"])
     files.update([file[len(folder2) + 1:] for file in files2 if file[-4:] == ".txt"])
   
   self.ui.lblDir1.setText(folder1)
   self.ui.lblDir2.setText(folder2)
   
   self.folder1        = folder1
   self.folder2        = folder2
   self.files          = set(files)
   self.files_nodupes  = None
   self.files_missing  = None
   
   self.saved_diffs    = {}
   
   self.show_files()
 def search_bar_old(self, dir, query):
   files = list_all_files(dir)
   
   progress = QProgressDialog("", "Abort", 0, len(files), self)
   progress.setWindowTitle("Searching...")
   progress.setWindowModality(Qt.Qt.WindowModal)
   progress.setValue(0)
   
   width = self.width()
   height = self.height()
   x = self.x()
   y = self.y()
   
   matches = []
   
   if not self.ui.chkRegEx.isChecked():
     query = re.escape(query)
   
   query_re = re.compile(query, re.IGNORECASE | re.DOTALL | re.UNICODE)
   
   for i, file in enumerate(files):
     
     if progress.wasCanceled():
       break
     
     if i % 500 == 0:
       progress.setLabelText(file)
       
       # Re-center the dialog.
       progress_w = progress.geometry().width()
       progress_h = progress.geometry().height()
       
       new_x = x + ((width - progress_w) / 2)
       new_y = y + ((height - progress_h) / 2)
       
       progress.move(new_x, new_y)
     
     if os.path.splitext(file)[1] == ".txt":
       text = load_text(file)
       if not query_re.search(text) == None:
         matches.append(file)
     
     progress.setValue(i + 1)
   
   progress.close()
   
   return matches
def pack_lin(dir):
  
  # Collect our files.
  file_list = sorted(list_all_files(dir))
  
  txt = [filename for filename in file_list if os.path.splitext(filename)[1].lower() == ".txt"]
  wrd = [filename for filename in file_list if os.path.splitext(filename)[1].lower() == ".wrd"]
  py  = [filename for filename in file_list if os.path.splitext(filename)[1].lower() == ".py"]
  
  # If there are more than one for whatever reason, just take the first.
  # We only have use for a single wrd or python file.
  wrd = wrd[0] if wrd else None
  py  = py[0]  if py  else None
  
  # Prepare our temporary output directory.
  temp_dir = tempfile.mkdtemp(prefix = "sdse-")
  
  # Where we're outputting our wrd file, regardless of whether it's a python
  # file or a raw binary data file.
  wrd_dst = os.path.join(temp_dir, "0.wrd")
  
  if py:
    try:
      wrd_file = WrdFile(py)
    except:
      _LOGGER.warning("%s failed to compile. Parsing wrd file instead. Exception info:\n%s" % (py, traceback.format_exc()))
      shutil.copy(wrd, wrd_dst)
    else:
      # If we succeeded in loading the python file, compile it to binary.
      wrd_file.save_bin(wrd_dst)
  
  else:
    shutil.copy(wrd, wrd_dst)
  
  # Pack the text files in-place to save us a bunch of copying
  # and then move it to the tmp directory with the wrd file.
  if txt:
    data = pack_pak(dir, file_list = txt, eof = True)
    with open(os.path.join(temp_dir, "1.dat"), "wb") as f:
      data.tofile(f)
  
  # Then pack it like normal.
  data = pack_pak(temp_dir, eof = True)
  shutil.rmtree(temp_dir)
  
  return data
    def list_txt_files(dir_filter=DEFAULT_FILTER):

        files = []
        for dir in ScriptAnalytics.list_dirs(dir_filter):
            temp_files = list_files.list_all_files(
                os.path.join(common.editor_config.umdimage_dir, dir))
            files.extend(temp_files)

        # For our dupe database, we need "umdimage" instead of wherever the files
        # are really stored, so we strip that part off first.
        dir_start = len(common.editor_config.umdimage_dir) + 1

        text_files = []

        for file in files:
            if os.path.splitext(file)[1] == ".txt":
                text_files.append(file[dir_start:])

        return text_files
 def list_untranslated(self):
   
   files = list_files.list_all_files(common.editor_config.data01_dir)
   #files = list_files.list_all_files("X:\\Danganronpa\\FULL_TEST\\best-normal")
   
   text_files = []
   
   for i, file in enumerate(files):
     if os.path.splitext(file)[1] == ".txt":
       text_files.append(file)
   
   for file in text_files:
     try:
       script_file = ScriptFile(file)
     except:
       print file
       continue
     
     if not script_file[common.editor_config.lang_trans] == "":
       print file
Example #12
0
def list_untranslated():
  
  files = list_files.list_all_files(common.editor_config.umdimage_dir)
  #files = list_files.list_all_files("X:\\Danganronpa\\FULL_TEST\\best-normal")
  
  text_files = []
  
  for i, file in enumerate(files):
    if os.path.splitext(file)[1] == ".txt":
      text_files.append(file)
  
  for file in text_files:
    try:
      script_file = ScriptFile(file)
    except:
      print file
      continue
    
    if not script_file.translated == "":
      print file
def import_umdimage(src, dst, convert_png = True, propogate = True, parent = None):
  src = os.path.abspath(src)
  dst = os.path.abspath(dst)
  if os.path.normcase(src) == os.path.normcase(dst):
    raise ValueError("Cannot import %s. Source and destination directories are the same." % src)
    
  answer = QtGui.QMessageBox.question(
    parent,
    "Import Directory",
    "Importing directory:\n\n" + src + "\n\n" +
    "into directory:\n\n" + dst + "\n\n" +
    "Any affected files will be backed up. Proceed?",
    buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
    defaultButton = QtGui.QMessageBox.No
  )
  
  if answer == QtGui.QMessageBox.No:
    return
  
  progress = QProgressDialog("Finding files...", "Cancel", 0, 1, parent)
  progress.setWindowTitle("Importing...")
  progress.setWindowModality(Qt.Qt.WindowModal)
  progress.setValue(0)
  progress.setAutoClose(False)
  progress.setMinimumDuration(0)
  
  if parent:
    width = parent.width()
    height = parent.height()
    x = parent.x()
    y = parent.y()
  else:
    width   = 1920
    height  = 1080
    x       = 0
    y       = 0
  
  progress.setMaximum(0)
  progress.setValue(0)
  
  # The raw list of files we're importing.
  files = []
  
  # A list of lists, including all dupes of the files being imported, too.
  affected_files = []
  file_count = 0
  
  dupe_base = "umdimage"
  tmp       = tempfile.mkdtemp(prefix = "sdse-")
  
  seen_groups = []
  
  count = 0
  last_update = time.time()
  
  for file in list_all_files(src):
    if progress.wasCanceled():
      break
    
    # Strip our base directory, so we have just a relative file list.
    file = os.path.normpath(os.path.normcase(file[len(src) + 1:]))
    files.append(file)
    
    count += 1
    if time.time() - last_update > MIN_INTERVAL or count % 25 == 0:
      last_update = time.time()
      progress.setLabelText("Finding files...\n" + file)
      # progress.setValue(count)
      progress.setValue(progress.value() ^ 1)
      
      # Re-center the dialog.
      progress_w = progress.geometry().width()
      progress_h = progress.geometry().height()
      
      new_x = x + ((width - progress_w) / 2)
      new_y = y + ((height - progress_h) / 2)
      
      progress.move(new_x, new_y)
    
    affected_files.append([])
    
    if os.path.splitext(file)[1] == ".png" and convert_png and file not in SKIP_CONV:
      file = os.path.splitext(file)[0] + ".gim"
    
    if propogate:
      file_group = _DUPE_DB.group_from_file(os.path.join(dupe_base, file))
    else:
      file_group = None
    
    if file_group in seen_groups:
      continue
    
    # If there are no dupes, just add this file.
    if file_group == None:
      affected_files[-1].append(file)
      file_count += 1
      continue
    
    seen_groups.append(file_group)
    for dupe in _DUPE_DB.files_in_group(file_group):
      # Minus the "umdimage" part
      dupe = dupe[len(dupe_base) + 1:]
      affected_files[-1].append(dupe)
      file_count += 1
  
  progress.setValue(0)
  progress.setMaximum(file_count)
  
  # Make a backup first.
  backup_dir = None
  count = 0
  for file_set in affected_files:
    if progress.wasCanceled():
      break
    for file in file_set:
      if progress.wasCanceled():
        break
      count += 1
      if time.time() - last_update > MIN_INTERVAL or count % 25 == 0:
        last_update = time.time()
        progress.setLabelText("Backing up...\n" + file)
        progress.setValue(count)
        
        # Re-center the dialog.
        progress_w = progress.geometry().width()
        progress_h = progress.geometry().height()
        
        new_x = x + ((width - progress_w) / 2)
        new_y = y + ((height - progress_h) / 2)
        
        progress.move(new_x, new_y)
      
      # It's perfectly possible we want to import some files that
      # don't already exist. Such as when importing a directory
      # with added lines.
      if not os.path.isfile(os.path.join(dst, file)):
        continue
        
      backup_dir = backup_files(dst, [file], suffix = "_IMPORT", backup_dir = backup_dir)
  
  progress.setValue(0)
  
  # And now do our importing.
  import_all_new = False
  skip_all_new = False
  count = 0
  for index, src_file in enumerate(files):
    if progress.wasCanceled():
      break
    
    if os.path.splitext(src_file)[1] == ".png" and convert_png and src_file not in SKIP_CONV:
      tmp_src_file = os.path.join(tmp, os.path.basename(src_file))
      tmp_src_file = os.path.splitext(tmp_src_file)[0] + ".gim"
      quantize = QuantizeType.auto
      for regex, q in FORCE_QUANTIZE:
        if not regex.search(src_file) == None:
          quantize = q
          break
      _CONV.png_to_gim(os.path.join(src, src_file), tmp_src_file, quantize)
      src_file = tmp_src_file
    
    else:
      src_file = os.path.join(src, src_file)
    
    for file in affected_files[index]:
      if progress.wasCanceled():
        break
      
      dst_file = os.path.join(dst, file)
      
      count += 1
      # if count % 25 == 0:
      if time.time() - last_update > MIN_INTERVAL or count % 25 == 0:
        last_update = time.time()
        progress.setLabelText("Importing...\n" + file)
        progress.setValue(count)
        
        # Re-center the dialog.
        progress_w = progress.geometry().width()
        progress_h = progress.geometry().height()
        
        new_x = x + ((width - progress_w) / 2)
        new_y = y + ((height - progress_h) / 2)
        
        progress.move(new_x, new_y)
      
      # We may be allowed to import files that don't exist, but we're
      # going to ask them about it anyway.
      if not os.path.isfile(dst_file):
        if skip_all_new:
          continue
        
        if not import_all_new:
          answer = QtGui.QMessageBox.question(
            parent,
            "File Not Found",
            "File:\n\n" + file + "\n\n" +
            "does not exist in the target directory. Import anyway?",
            buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.YesToAll | QtGui.QMessageBox.No | QtGui.QMessageBox.NoToAll,
            defaultButton = QtGui.QMessageBox.No
          )
          
          if answer == QtGui.QMessageBox.YesToAll:
            import_all_new = True
            skip_all_new = False
          elif answer == QtGui.QMessageBox.NoToAll:
            skip_all_new = True
            import_all_new = False
            continue
          elif answer == QtGui.QMessageBox.No:
            continue
      
      basedir = os.path.dirname(dst_file)
      if not os.path.isdir(basedir):
        os.makedirs(basedir)
      
      shutil.copy2(src_file, dst_file)
  
  shutil.rmtree(tmp)
  progress.close()
    def load_dir(self, directory, umdimage="umdimage"):

        self.script_files = []
        self.directory = directory
        self.wrd = None
        self.wrd_file = None
        self.py_file = None

        base_name = directory
        directory, wrd_file = dir_tools.parse_dir(directory, umdimage)

        if directory == None:
            self.directory = ""
            raise Exception("Directory \"" + base_name + "\" not found.")

        full_dir = os.path.join(umdimage, directory)

        scene_info = []

        if not wrd_file == None and os.path.isfile(wrd_file):

            # Even of the first directory existed and we have a .wrd file,
            # it's possible there aren't actually any text files here.
            if not os.path.isdir(full_dir):
                raise Exception("There are no text files in \"" + directory +
                                "\".")

            self.wrd = WrdFile()

            py_file = os.path.splitext(wrd_file)[0] + ".py"

            if os.path.isfile(py_file):
                try:
                    self.wrd.load_python(py_file)
                except:
                    _LOGGER.warning(
                        "%s failed to load. Parsing wrd file instead. Exception info:\n%s"
                        % (py_file, traceback.format_exc()))
                    self.wrd.load_bin(wrd_file)
                else:
                    # If we succeeded in loading the python file, compile it to binary.
                    # _LOGGER.info("%s loaded successfully. Compiling to binary." % py_file)
                    # self.wrd.save_bin(wrd_file)
                    _LOGGER.info("%s loaded successfully." % py_file)

            else:
                _LOGGER.info("Decompiled wrd file not found. Generating %s" %
                             py_file)
                self.wrd.load_bin(wrd_file)
                self.wrd.save_python(py_file)

            scene_info = self.wrd.to_scene_info()
            self.wrd_file = wrd_file
            self.py_file = py_file

        else:
            scene_info = None
            self.wrd = None
            self.wrd_file = None

        self.script_files = []
        if scene_info == None:
            text_files = list_all_files(full_dir)
            for file in text_files:
                self.script_files.append(ScriptFile(file))

        else:
            # Get our files in the order listed by the wrd.
            for info in scene_info:
                filename = os.path.join(full_dir, "%04d.txt" % info.file_id)
                script_file = ScriptFile(filename, info)

                if script_file.filename == None:
                    _LOGGER.warning(
                        "File %s referenced by %s does not exist." %
                        (filename, wrd_file))
                    continue

                self.script_files.append(script_file)

        chapter, scene, room, mode = common.get_dir_info(base_name)

        for file in self.script_files:
            if file.scene_info.chapter == -1: file.scene_info.chapter = chapter
            if file.scene_info.scene == -1: file.scene_info.scene = scene
            if file.scene_info.room == -1: file.scene_info.room = room
            if file.scene_info.mode == None: file.scene_info.mode = mode
def import_umdimage2(src, dst, convert_png = True, propogate = True, parent = None):
  src = os.path.abspath(src)
  dst = os.path.abspath(dst)
  if os.path.normcase(src) == os.path.normcase(dst):
    raise ValueError("Cannot import %s. Source and destination directories are the same." % src)
    
  answer = QtGui.QMessageBox.question(
    parent,
    "Import Directory",
    "Importing directory:\n\n" + src + "\n\n" +
    "into directory:\n\n" + dst + "\n\n" +
    "Any affected files will be backed up. Proceed?",
    buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
    defaultButton = QtGui.QMessageBox.No
  )
  
  if answer == QtGui.QMessageBox.No:
    return
  
  progress = QProgressDialog("Importing...", "Cancel", 0, 0, parent)
  progress.setWindowTitle("Importing...")
  progress.setWindowModality(Qt.Qt.WindowModal)
  progress.setValue(0)
  progress.setAutoClose(False)
  progress.setMinimumDuration(0)
  
  tmp_dst     = tempfile.mkdtemp(prefix = "sdse-")
  backup_dir  = None
  
  for pak in glob.iglob(os.path.join(src, "bg_*.pak")):
    if progress.wasCanceled():
      break
    
    pak_name    = os.path.basename(pak)
    backup_dir  = backup_files(dst, [pak_name], suffix = "_IMPORT", backup_dir = backup_dir)
    
    # If we have a regular file with the bg_*.pak name, then just drop it in.
    if os.path.isfile(pak):
      progress.setLabelText("Importing:\n" + pak_name)
      progress.setValue(progress.value() ^ 1)
      shutil.copy2(pak, os.path.join(dst, pak_name))
    
    # Otherwise, if it's a directory, insert all the textures we find
    # into the target bg_*.pak file.
    elif os.path.isdir(pak):
      for image in list_all_files(pak):
        if progress.wasCanceled():
          break
        
        ext = os.path.splitext(image)[1].lower()
        if ext == ".png" and not convert_png:
          continue
        
        base_name = image[len(src) + 1:]
        dst_files = []
        
        if propogate:
          dupe_name = os.path.splitext(base_name)[0] + ".gim"
          dupe_name = os.path.join("umdimage2", dupe_name)
          dupe_name = os.path.normpath(os.path.normcase(dupe_name))
        
          dupes = _DUPE_DB.files_in_same_group(dupe_name)
          
          if dupes == None:
            dupes = [dupe_name]
          
          for dupe in dupes:
            dst_file = dupe[10:] # chop off the "umdimage2/"
            dst_file = os.path.splitext(dst_file)[0] + ext # original extension
            dst_file = os.path.join(tmp_dst, dst_file)
            dst_files.append(dst_file)
        
        else:
          dst_files = [os.path.join(tmp_dst, base_name)]
        
        for dst_file in dst_files:
          try:
            os.makedirs(os.path.dirname(dst_file))
          except:
            pass
          shutil.copy(image, dst_file)
      
      if progress.wasCanceled():
        break
    
      progress.setLabelText("Inserting textures into:\n" + pak_name)
      progress.setValue(progress.value() ^ 1)
      
      pak_dir   = os.path.join(tmp_dst, pak_name)
      pak_file  = os.path.join(dst, pak_name)
      
      # If we didn't copy anything over, just move on.
      if not os.path.isdir(pak_dir):
        continue
      
      thread = threading.Thread(target = insert_textures, args = (pak_dir, pak_file))
      thread.start()
      
      while thread.isAlive():
        thread.join(MIN_INTERVAL)
        progress.setValue(progress.value() ^ 1)
        
        if progress.wasCanceled():
          progress.setLabelText("Canceling...")
  
  shutil.rmtree(tmp_dst)
  progress.close()
def export_umdimage(src, dst, convert_gim = True, unique = False, parent = None):
  src = os.path.abspath(src)
  dst = os.path.abspath(dst)
  if os.path.normcase(src) == os.path.normcase(dst):
    raise ValueError("Cannot export %s. Source and destination directories are the same." % src)
    
  answer = QtGui.QMessageBox.question(
    parent,
    "Export Directory",
    "Exporting directory:\n\n" + src + "\n\n" +
    "into directory:\n\n" + dst + "\n\n" +
    "Proceed?",
    buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
    defaultButton = QtGui.QMessageBox.No
  )
  
  if answer == QtGui.QMessageBox.No:
    return
  
  progress = QProgressDialog("Exporting...", "Cancel", 0, 0, parent)
  progress.setWindowTitle("Exporting...")
  progress.setWindowModality(Qt.Qt.WindowModal)
  progress.setValue(0)
  progress.setAutoClose(False)
  progress.setMinimumDuration(0)
  
  if parent:
    width = parent.width()
    height = parent.height()
    x = parent.x()
    y = parent.y()
  else:
    width   = 1920
    height  = 1080
    x       = 0
    y       = 0
  
  seen_groups = []
  
  count = 0
  last_update = time.time()
  progress.setMaximum(60000)
  
  for filename in list_all_files(src):
    if progress.wasCanceled():
      break
    
    count += 1
    if time.time() - last_update > MIN_INTERVAL or count % 25 == 0:
      last_update = time.time()
      progress.setLabelText("Exporting...\n" + filename)
      progress.setValue(count)
      
      # Re-center the dialog.
      progress_w = progress.geometry().width()
      progress_h = progress.geometry().height()
      
      new_x = x + ((width - progress_w) / 2)
      new_y = y + ((height - progress_h) / 2)
      
      progress.move(new_x, new_y)
    
    base_name = filename[len(src) + 1:]
    if unique:
      dupe_name = os.path.join("umdimage", base_name)
      dupe_name = os.path.normpath(os.path.normcase(dupe_name))
      
      group = _DUPE_DB.group_from_file(dupe_name)
      
      if group in seen_groups:
        continue
      
      if not group == None:
        seen_groups.append(group)
    
    dst_file = os.path.join(dst, base_name)
    dst_dir  = os.path.dirname(dst_file)
    ext      = os.path.splitext(dst_file)[1].lower()
    
    try:
      os.makedirs(dst_dir)
    except:
      pass
    
    if ext == ".gim" and convert_gim:
      dst_file = os.path.splitext(dst_file)[0] + ".png"
      _CONV.gim_to_png(filename, dst_file)
    else:
      shutil.copy2(filename, dst_file)
  
  progress.close()
def export_umdimage2(src, dst, convert_gim = True, unique = False, parent = None):
  src = os.path.abspath(src)
  dst = os.path.abspath(dst)
  if os.path.normcase(src) == os.path.normcase(dst):
    raise ValueError("Cannot export %s. Source and destination directories are the same." % src)
    
  answer = QtGui.QMessageBox.question(
    parent,
    "Export Directory",
    "Exporting directory:\n\n" + src + "\n\n" +
    "into directory:\n\n" + dst + "\n\n" +
    "Proceed?",
    buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
    defaultButton = QtGui.QMessageBox.No
  )
  
  if answer == QtGui.QMessageBox.No:
    return
  
  progress = QProgressDialog("Exporting...", "Cancel", 0, 0, parent)
  progress.setWindowTitle("Exporting...")
  progress.setWindowModality(Qt.Qt.WindowModal)
  progress.setValue(0)
  progress.setAutoClose(False)
  progress.setMinimumDuration(0)
  
  if unique:
    tmp_dst = tempfile.mkdtemp(prefix = "sdse-")
  else:
    tmp_dst = dst
  
  seen_groups = []
  
  for pak in glob.iglob(os.path.join(src, "bg_*.pak")):
    if progress.wasCanceled():
      break
    
    pak_name = os.path.basename(pak)
    out_dir  = os.path.join(tmp_dst, pak_name)
  
    progress.setLabelText("Extracting:\n" + pak)
    
    thread = threading.Thread(target = extract_model_pak, args = (pak, out_dir, convert_gim))
    thread.start()
    
    while thread.isAlive():
      thread.join(MIN_INTERVAL)
      progress.setValue(progress.value() ^ 1)
      
      if progress.wasCanceled():
        progress.setLabelText("Canceling...")
    
    if progress.wasCanceled():
      break
  
    if unique:
      for img in list_all_files(out_dir):
        img_base  = img[len(tmp_dst) + 1:]
        dupe_name = os.path.splitext(img_base)[0] + ".gim"
        dupe_name = os.path.join("umdimage2", dupe_name)
        dupe_name = os.path.normpath(os.path.normcase(dupe_name))
        
        group = _DUPE_DB.group_from_file(dupe_name)
        
        if group in seen_groups:
          continue
        
        if not group == None:
          seen_groups.append(group)
        
        dst_file = os.path.join(dst, img_base)
        dst_dir  = os.path.dirname(dst_file)
        
        try:
          os.makedirs(dst_dir)
        except:
          pass
        
        shutil.copy2(img, dst_file)
      
      shutil.rmtree(out_dir)
  
  if unique:
    shutil.rmtree(tmp_dst)
  
  progress.close()
def export_umdimage2(src, dst, convert_gim=True, unique=False, parent=None):
    src = os.path.abspath(src)
    dst = os.path.abspath(dst)
    if os.path.normcase(src) == os.path.normcase(dst):
        raise ValueError(
            "Cannot export %s. Source and destination directories are the same."
            % src)

    answer = QtGui.QMessageBox.question(
        parent,
        "Export Directory",
        "Exporting directory:\n\n" + src + "\n\n" + "into directory:\n\n" +
        dst + "\n\n" + "Proceed?",
        buttons=QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
        defaultButton=QtGui.QMessageBox.No)

    if answer == QtGui.QMessageBox.No:
        return

    progress = QProgressDialog("Exporting...", "Cancel", 0, 0, parent)
    progress.setWindowTitle("Exporting...")
    progress.setWindowModality(Qt.Qt.WindowModal)
    progress.setValue(0)
    progress.setAutoClose(False)
    progress.setMinimumDuration(0)

    if unique:
        tmp_dst = tempfile.mkdtemp(prefix="sdse-")
    else:
        tmp_dst = dst

    seen_groups = []

    for pak in glob.iglob(os.path.join(src, "bg_*.pak")):
        if progress.wasCanceled():
            break

        pak_name = os.path.basename(pak)
        out_dir = os.path.join(tmp_dst, pak_name)

        progress.setLabelText("Extracting:\n" + pak)

        thread = threading.Thread(target=extract_model_pak,
                                  args=(pak, out_dir, convert_gim))
        thread.start()

        while thread.isAlive():
            thread.join(MIN_INTERVAL)
            progress.setValue(progress.value() ^ 1)

            if progress.wasCanceled():
                progress.setLabelText("Canceling...")

        if progress.wasCanceled():
            break

        if unique:
            for img in list_all_files(out_dir):
                img_base = img[len(tmp_dst) + 1:]
                dupe_name = os.path.splitext(img_base)[0] + ".gim"
                dupe_name = os.path.join("umdimage2", dupe_name)
                dupe_name = os.path.normpath(os.path.normcase(dupe_name))

                group = _DUPE_DB.group_from_file(dupe_name)

                if group in seen_groups:
                    continue

                if not group == None:
                    seen_groups.append(group)

                dst_file = os.path.join(dst, img_base)
                dst_dir = os.path.dirname(dst_file)

                try:
                    os.makedirs(dst_dir)
                except:
                    pass

                shutil.copy2(img, dst_file)

            shutil.rmtree(out_dir)

    if unique:
        shutil.rmtree(tmp_dst)

    progress.close()
def import_umdimage2(src, dst, convert_png=True, propogate=True, parent=None):
    src = os.path.abspath(src)
    dst = os.path.abspath(dst)
    if os.path.normcase(src) == os.path.normcase(dst):
        raise ValueError(
            "Cannot import %s. Source and destination directories are the same."
            % src)

    answer = QtGui.QMessageBox.question(
        parent,
        "Import Directory",
        "Importing directory:\n\n" + src + "\n\n" + "into directory:\n\n" +
        dst + "\n\n" + "Any affected files will be backed up. Proceed?",
        buttons=QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
        defaultButton=QtGui.QMessageBox.No)

    if answer == QtGui.QMessageBox.No:
        return

    progress = QProgressDialog("Importing...", "Cancel", 0, 0, parent)
    progress.setWindowTitle("Importing...")
    progress.setWindowModality(Qt.Qt.WindowModal)
    progress.setValue(0)
    progress.setAutoClose(False)
    progress.setMinimumDuration(0)

    tmp_dst = tempfile.mkdtemp(prefix="sdse-")
    backup_dir = None

    for pak in glob.iglob(os.path.join(src, "bg_*.pak")):
        if progress.wasCanceled():
            break

        pak_name = os.path.basename(pak)
        backup_dir = backup_files(dst, [pak_name],
                                  suffix="_IMPORT",
                                  backup_dir=backup_dir)

        # If we have a regular file with the bg_*.pak name, then just drop it in.
        if os.path.isfile(pak):
            progress.setLabelText("Importing:\n" + pak_name)
            progress.setValue(progress.value() ^ 1)
            shutil.copy2(pak, os.path.join(dst, pak_name))

        # Otherwise, if it's a directory, insert all the textures we find
        # into the target bg_*.pak file.
        elif os.path.isdir(pak):
            for image in list_all_files(pak):
                if progress.wasCanceled():
                    break

                ext = os.path.splitext(image)[1].lower()
                if ext == ".png" and not convert_png:
                    continue

                base_name = image[len(src) + 1:]
                dst_files = []

                if propogate:
                    dupe_name = os.path.splitext(base_name)[0] + ".gim"
                    dupe_name = os.path.join("umdimage2", dupe_name)
                    dupe_name = os.path.normpath(os.path.normcase(dupe_name))

                    dupes = _DUPE_DB.files_in_same_group(dupe_name)

                    if dupes == None:
                        dupes = [dupe_name]

                    for dupe in dupes:
                        dst_file = dupe[10:]  # chop off the "umdimage2/"
                        dst_file = os.path.splitext(
                            dst_file)[0] + ext  # original extension
                        dst_file = os.path.join(tmp_dst, dst_file)
                        dst_files.append(dst_file)

                else:
                    dst_files = [os.path.join(tmp_dst, base_name)]

                for dst_file in dst_files:
                    try:
                        os.makedirs(os.path.dirname(dst_file))
                    except:
                        pass
                    shutil.copy(image, dst_file)

            if progress.wasCanceled():
                break

            progress.setLabelText("Inserting textures into:\n" + pak_name)
            progress.setValue(progress.value() ^ 1)

            pak_dir = os.path.join(tmp_dst, pak_name)
            pak_file = os.path.join(dst, pak_name)

            # If we didn't copy anything over, just move on.
            if not os.path.isdir(pak_dir):
                continue

            thread = threading.Thread(target=insert_textures,
                                      args=(pak_dir, pak_file))
            thread.start()

            while thread.isAlive():
                thread.join(MIN_INTERVAL)
                progress.setValue(progress.value() ^ 1)

                if progress.wasCanceled():
                    progress.setLabelText("Canceling...")

    shutil.rmtree(tmp_dst)
    progress.close()
def export_umdimage(src, dst, convert_gim=True, unique=False, parent=None):
    src = os.path.abspath(src)
    dst = os.path.abspath(dst)
    if os.path.normcase(src) == os.path.normcase(dst):
        raise ValueError(
            "Cannot export %s. Source and destination directories are the same."
            % src)

    answer = QtGui.QMessageBox.question(
        parent,
        "Export Directory",
        "Exporting directory:\n\n" + src + "\n\n" + "into directory:\n\n" +
        dst + "\n\n" + "Proceed?",
        buttons=QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
        defaultButton=QtGui.QMessageBox.No)

    if answer == QtGui.QMessageBox.No:
        return

    progress = QProgressDialog("Exporting...", "Cancel", 0, 0, parent)
    progress.setWindowTitle("Exporting...")
    progress.setWindowModality(Qt.Qt.WindowModal)
    progress.setValue(0)
    progress.setAutoClose(False)
    progress.setMinimumDuration(0)

    if parent:
        width = parent.width()
        height = parent.height()
        x = parent.x()
        y = parent.y()
    else:
        width = 1920
        height = 1080
        x = 0
        y = 0

    seen_groups = []

    count = 0
    last_update = time.time()
    progress.setMaximum(60000)

    for filename in list_all_files(src):
        if progress.wasCanceled():
            break

        count += 1
        if time.time() - last_update > MIN_INTERVAL or count % 25 == 0:
            last_update = time.time()
            progress.setLabelText("Exporting...\n" + filename)
            progress.setValue(count)

            # Re-center the dialog.
            progress_w = progress.geometry().width()
            progress_h = progress.geometry().height()

            new_x = x + ((width - progress_w) / 2)
            new_y = y + ((height - progress_h) / 2)

            progress.move(new_x, new_y)

        base_name = filename[len(src) + 1:]
        if unique:
            dupe_name = os.path.join("umdimage", base_name)
            dupe_name = os.path.normpath(os.path.normcase(dupe_name))

            group = _DUPE_DB.group_from_file(dupe_name)

            if group in seen_groups:
                continue

            if not group == None:
                seen_groups.append(group)

        dst_file = os.path.join(dst, base_name)
        dst_dir = os.path.dirname(dst_file)
        ext = os.path.splitext(dst_file)[1].lower()

        try:
            os.makedirs(dst_dir)
        except:
            pass

        if ext == ".gim" and convert_gim:
            dst_file = os.path.splitext(dst_file)[0] + ".png"
            _CONV.gim_to_png(filename, dst_file)
        else:
            shutil.copy2(filename, dst_file)

    progress.close()
def backup_directory(source_dir, suffix="_SAVE"):
    files = [file[len(source_dir) + 1:] for file in list_all_files(source_dir)]
    backup_files(source_dir, files, suffix)
def import_umdimage(src, dst, convert_png=True, propogate=True, parent=None):
    src = os.path.abspath(src)
    dst = os.path.abspath(dst)
    if os.path.normcase(src) == os.path.normcase(dst):
        raise ValueError(
            "Cannot import %s. Source and destination directories are the same."
            % src)

    answer = QtGui.QMessageBox.question(
        parent,
        "Import Directory",
        "Importing directory:\n\n" + src + "\n\n" + "into directory:\n\n" +
        dst + "\n\n" + "Any affected files will be backed up. Proceed?",
        buttons=QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
        defaultButton=QtGui.QMessageBox.No)

    if answer == QtGui.QMessageBox.No:
        return

    progress = QProgressDialog("Finding files...", "Cancel", 0, 1, parent)
    progress.setWindowTitle("Importing...")
    progress.setWindowModality(Qt.Qt.WindowModal)
    progress.setValue(0)
    progress.setAutoClose(False)
    progress.setMinimumDuration(0)

    if parent:
        width = parent.width()
        height = parent.height()
        x = parent.x()
        y = parent.y()
    else:
        width = 1920
        height = 1080
        x = 0
        y = 0

    progress.setMaximum(0)
    progress.setValue(0)

    # The raw list of files we're importing.
    files = []

    # A list of lists, including all dupes of the files being imported, too.
    affected_files = []
    file_count = 0

    dupe_base = "umdimage"
    tmp = tempfile.mkdtemp(prefix="sdse-")

    seen_groups = []

    count = 0
    last_update = time.time()

    for file in list_all_files(src):
        if progress.wasCanceled():
            break

        # Strip our base directory, so we have just a relative file list.
        file = os.path.normpath(os.path.normcase(file[len(src) + 1:]))
        files.append(file)

        count += 1
        if time.time() - last_update > MIN_INTERVAL or count % 25 == 0:
            last_update = time.time()
            progress.setLabelText("Finding files...\n" + file)
            # progress.setValue(count)
            progress.setValue(progress.value() ^ 1)

            # Re-center the dialog.
            progress_w = progress.geometry().width()
            progress_h = progress.geometry().height()

            new_x = x + ((width - progress_w) / 2)
            new_y = y + ((height - progress_h) / 2)

            progress.move(new_x, new_y)

        affected_files.append([])

        if os.path.splitext(
                file)[1] == ".png" and convert_png and file not in SKIP_CONV:
            file = os.path.splitext(file)[0] + ".gim"

        if propogate:
            file_group = _DUPE_DB.group_from_file(os.path.join(
                dupe_base, file))
        else:
            file_group = None

        if file_group in seen_groups:
            continue

        # If there are no dupes, just add this file.
        if file_group == None:
            affected_files[-1].append(file)
            file_count += 1
            continue

        seen_groups.append(file_group)
        for dupe in _DUPE_DB.files_in_group(file_group):
            # Minus the "umdimage" part
            dupe = dupe[len(dupe_base) + 1:]
            affected_files[-1].append(dupe)
            file_count += 1

    progress.setValue(0)
    progress.setMaximum(file_count)

    # Make a backup first.
    backup_dir = None
    count = 0
    for file_set in affected_files:
        if progress.wasCanceled():
            break
        for file in file_set:
            if progress.wasCanceled():
                break
            count += 1
            if time.time() - last_update > MIN_INTERVAL or count % 25 == 0:
                last_update = time.time()
                progress.setLabelText("Backing up...\n" + file)
                progress.setValue(count)

                # Re-center the dialog.
                progress_w = progress.geometry().width()
                progress_h = progress.geometry().height()

                new_x = x + ((width - progress_w) / 2)
                new_y = y + ((height - progress_h) / 2)

                progress.move(new_x, new_y)

            # It's perfectly possible we want to import some files that
            # don't already exist. Such as when importing a directory
            # with added lines.
            if not os.path.isfile(os.path.join(dst, file)):
                continue

            backup_dir = backup_files(dst, [file],
                                      suffix="_IMPORT",
                                      backup_dir=backup_dir)

    progress.setValue(0)

    # And now do our importing.
    import_all_new = False
    skip_all_new = False
    count = 0
    for index, src_file in enumerate(files):
        if progress.wasCanceled():
            break

        if os.path.splitext(src_file)[
                1] == ".png" and convert_png and src_file not in SKIP_CONV:
            tmp_src_file = os.path.join(tmp, os.path.basename(src_file))
            tmp_src_file = os.path.splitext(tmp_src_file)[0] + ".gim"
            quantize = QuantizeType.auto
            for regex, q in FORCE_QUANTIZE:
                if not regex.search(src_file) == None:
                    quantize = q
                    break
            _CONV.png_to_gim(os.path.join(src, src_file), tmp_src_file,
                             quantize)
            src_file = tmp_src_file

        else:
            src_file = os.path.join(src, src_file)

        for file in affected_files[index]:
            if progress.wasCanceled():
                break

            dst_file = os.path.join(dst, file)

            count += 1
            # if count % 25 == 0:
            if time.time() - last_update > MIN_INTERVAL or count % 25 == 0:
                last_update = time.time()
                progress.setLabelText("Importing...\n" + file)
                progress.setValue(count)

                # Re-center the dialog.
                progress_w = progress.geometry().width()
                progress_h = progress.geometry().height()

                new_x = x + ((width - progress_w) / 2)
                new_y = y + ((height - progress_h) / 2)

                progress.move(new_x, new_y)

            # We may be allowed to import files that don't exist, but we're
            # going to ask them about it anyway.
            if not os.path.isfile(dst_file):
                if skip_all_new:
                    continue

                if not import_all_new:
                    answer = QtGui.QMessageBox.question(
                        parent,
                        "File Not Found",
                        "File:\n\n" + file + "\n\n" +
                        "does not exist in the target directory. Import anyway?",
                        buttons=QtGui.QMessageBox.Yes
                        | QtGui.QMessageBox.YesToAll | QtGui.QMessageBox.No
                        | QtGui.QMessageBox.NoToAll,
                        defaultButton=QtGui.QMessageBox.No)

                    if answer == QtGui.QMessageBox.YesToAll:
                        import_all_new = True
                        skip_all_new = False
                    elif answer == QtGui.QMessageBox.NoToAll:
                        skip_all_new = True
                        import_all_new = False
                        continue
                    elif answer == QtGui.QMessageBox.No:
                        continue

            basedir = os.path.dirname(dst_file)
            if not os.path.isdir(basedir):
                os.makedirs(basedir)

            shutil.copy2(src_file, dst_file)

    shutil.rmtree(tmp)
    progress.close()
def backup_directory(source_dir, suffix = "_SAVE"):
  files = [file[len(source_dir) + 1:] for file in list_all_files(source_dir)]
  backup_files(source_dir, files, suffix)