def _open_subarchive(self, dir, path): """Allows to recursively extract all subarchives""" fullpath = os.path.join(dir, path) extractor = archive.Extractor() condition = extractor.setup(fullpath, dir) sub_files = extractor.get_files() alphanumeric_sort(sub_files) extractor.set_files(sub_files) extractor.extract() for name in sub_files: condition.acquire() while not extractor.is_ready(name): condition.wait() condition.release() dname = dir + "/" + name name_type = archive.archive_mime_type(dname) if archive.archive_mime_type(dname) not in (None, archive.DIRECTORY,): self._open_subarchive(os.path.dirname(dir), os.path.basename(name)) if not os.path.isdir(fullpath): os.remove(fullpath)
def _get_new_thumbnail(path, create, dst_dir): """Return a new thumbnail pixbuf for the file at <path>. If <create> is True we also save it to disk with <dst_dir> as the base thumbnail directory. """ if archive.archive_mime_type(path) is not None: if create: return _get_new_archive_thumbnail(path, dst_dir) return None if create: return _create_thumbnail(path, dst_dir) return _get_pixbuf128(path)
def _open_previous_archive(self): """Open the archive that comes directly before the currently loaded archive in that archive's directory listing, sorted alphabetically. """ arch_dir = os.path.dirname(self._base_path) files = list_dir_sorted(arch_dir) try: current_index = files.index(os.path.basename(self._base_path)) except ValueError: return for f in reversed(files[:current_index]): path = os.path.join(arch_dir, f) if archive.archive_mime_type(path) is not None: self.open_file(path, 0) return
def _open_subarchive(self, dir, path): """Allows to recursively extract all subarchives""" fullpath = os.path.join(dir, path) extractor = archive.Extractor() condition = extractor.setup(fullpath, dir) sub_files = extractor.get_files() alphanumeric_sort(sub_files) extractor.set_files(sub_files) extractor.extract() for name in sub_files: condition.acquire() while not extractor.is_ready(name): condition.wait() condition.release() dname = dir + "/" + name name_type = archive.archive_mime_type(dname) if archive.archive_mime_type(dname) not in ( None, archive.DIRECTORY, ): self._open_subarchive(os.path.dirname(dir), os.path.basename(name)) if not os.path.isdir(fullpath): os.remove(fullpath)
def _open_next_archive(self): """Open the archive that comes directly after the currently loaded archive in that archive's directory listing, sorted alphabetically. """ arch_dir = os.path.dirname(self._base_path) files = os.listdir(arch_dir) files.sort(locale.strcoll) try: current_index = files.index(os.path.basename(self._base_path)) except ValueError: return for f in files[current_index + 1:]: path = os.path.join(arch_dir, f) if archive.archive_mime_type(path) is not None: self.open_file(path) return
def _open_subarchive(self, dir, path): """Allows to recursively extract all subarchives""" extractor = archive.Extractor() condition = extractor.setup(dir + "/" + path, dir) sub_files = extractor.get_files() alphanumeric_sort(sub_files) extractor.set_files(sub_files) extractor.extract() for name in sub_files: condition.acquire() while not extractor.is_ready(name): condition.wait() condition.release() name = dir + "/" + name if archive.archive_mime_type(name) is not None: self._open_subarchive(os.path.dirname(name), os.path.basename(name)) os.remove(dir + "/" + path)
def open_file(self, path, start_page=1): """Open the file pointed to by <path>. If <start_page> is not set we set the current page to 1 (first page), if it is set we set the current page to the value of <start_page>. If <start_page> is non-positive it means the last image. Return True if the file is successfully loaded. """ # If the given <path> is invalid we update the statusbar. if os.path.isdir(path): self._window.statusbar.set_message( _('Could not open %s: Is a directory.') % path) return False if not os.path.isfile(path): self._window.statusbar.set_message( _('Could not open %s: No such file.') % path) return False if not os.access(path, os.R_OK): self._window.statusbar.set_message( _('Could not open %s: Permission denied.') % path) return False self.archive_type = archive.archive_mime_type(path) if self.archive_type is None and not is_image_file(path): self._window.statusbar.set_message( _('Could not open %s: Unknown file type.') % path) return False # We close the previously opened file. self._window.cursor_handler.set_cursor_type(cursor.WAIT) if self.file_loaded: self.close_file() while gtk.events_pending(): gtk.main_iteration(False) # If <path> is an archive we create an Extractor for it and set the # files in it with file endings indicating image files or comments # as the ones to be extracted. if self.archive_type is not None: self._base_path = path self._condition = self._extractor.setup(path, self._tmp_dir) files = self._extractor.get_files() image_files = filter(self._image_re.search, files) if (prefs['random image']): shuffle(image_files) else: alphanumeric_sort(image_files) self._image_files = \ [os.path.join(self._tmp_dir, f) for f in image_files] comment_files = filter(self._comment_re.search, files) self._comment_files = \ [os.path.join(self._tmp_dir, f) for f in comment_files] for name, full_path in zip(image_files, self._image_files): self._name_table[full_path] = name for name, full_path in zip(comment_files, self._comment_files): self._name_table[full_path] = name if start_page <= 0: if self._window.is_double_page: self._current_image_index = self.get_number_of_pages() - 2 else: self._current_image_index = self.get_number_of_pages() - 1 else: self._current_image_index = start_page - 1 self._current_image_index = max(0, self._current_image_index) depth = self._window.is_double_page and 2 or 1 priority_ordering = (range(self._current_image_index, self._current_image_index + depth * 2) + range(self._current_image_index - depth, self._current_image_index)[::-1]) priority_ordering = [ image_files[p] for p in priority_ordering if 0 <= p <= self.get_number_of_pages() - 1 ] for i, name in enumerate(priority_ordering): image_files.remove(name) image_files.insert(i, name) self._extractor.set_files(image_files + comment_files) self._extractor.extract() # If <path> is an image we scan its directory for more images. else: self._base_path = os.path.dirname(path) for f in os.listdir(self._base_path): fpath = os.path.join(self._base_path, f) if is_image_file(fpath): self._image_files.append(fpath) if (prefs['random image']): shuffle(self._image_files) else: self._image_files.sort(locale.strcoll) self._current_image_index = self._image_files.index(path) if not self._image_files: self._window.statusbar.set_message( _("No images in '%s'") % os.path.basename(path)) self.file_loaded = False else: self.file_loaded = True alphanumeric_sort(self._comment_files) self._window.cursor_handler.set_cursor_type(cursor.NORMAL) self._window.ui_manager.set_sensitivities() self._window.new_page() self._window.ui_manager.recent.add(path)
def open_file(self, path, start_page=1): """Open the file pointed to by <path>. If <start_page> is not set we set the current page to 1 (first page), if it is set we set the current page to the value of <start_page>. If <start_page> is non-positive it means the last image. Return True if the file is successfully loaded. """ # If the given <path> is invalid we update the statusbar. if os.path.isdir(path): self._window.statusbar.set_message( _('Could not open %s: Is a directory.') % path) return False if not os.path.isfile(path): self._window.statusbar.set_message( _('Could not open %s: No such file.') % path) return False if not os.access(path, os.R_OK): self._window.statusbar.set_message( _('Could not open %s: Permission denied.') % path) return False self.archive_type = archive.archive_mime_type(path) if self.archive_type is None and not is_image_file(path): self._window.statusbar.set_message( _('Could not open %s: Unknown file type.') % path) return False # We close the previously opened file. self._window.cursor_handler.set_cursor_type(cursor.WAIT) if self.file_loaded: self.close_file() while gtk.events_pending(): gtk.main_iteration(False) # If <path> is an archive we create an Extractor for it and set the # files in it with file endings indicating image files or comments # as the ones to be extracted. if self.archive_type is not None: self._base_path = path self._condition = self._extractor.setup(path, self._tmp_dir) if self._extractor.need_password(): label = gtk.Label("Password:"******"Password required", None, gtk.DIALOG_MODAL, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) dialog.vbox.pack_start(label) dialog.vbox.pack_start(entry) label.show() entry.show() resp = dialog.run() if resp == gtk.RESPONSE_ACCEPT: self._extractor.set_password(entry.get_text()) dialog.destroy() files = self._extractor.get_files() image_files = filter(self._image_re.search, files) alphanumeric_sort(image_files) self._image_files = \ [os.path.join(self._tmp_dir, f) for f in image_files] comment_files = filter(self._comment_re.search, files) self._comment_files = \ [os.path.join(self._tmp_dir, f) for f in comment_files] for name, full_path in zip(image_files, self._image_files): self._name_table[full_path] = name for name, full_path in zip(comment_files, self._comment_files): self._name_table[full_path] = name if start_page <= 0: if self._window.is_double_page: self._current_image_index = self.get_number_of_pages() - 2 else: self._current_image_index = self.get_number_of_pages() - 1 else: self._current_image_index = start_page - 1 self._current_image_index = max(0, self._current_image_index) depth = self._window.is_double_page and 2 or 1 priority_ordering = ( range(self._current_image_index, self._current_image_index + depth * 2) + range(self._current_image_index - depth, self._current_image_index)[::-1]) priority_ordering = [image_files[p] for p in priority_ordering if 0 <= p <= self.get_number_of_pages() - 1] for i, name in enumerate(priority_ordering): image_files.remove(name) image_files.insert(i, name) self._extractor.set_files(image_files + comment_files) self._extractor.extract() # If <path> is an image we scan its directory for more images. else: self._base_path = os.path.dirname(path) for f in os.listdir(self._base_path): fpath = os.path.join(self._base_path, f) if is_image_file(fpath): self._image_files.append(fpath) self._image_files.sort(locale.strcoll) self._current_image_index = self._image_files.index(path) if not self._image_files: self._window.statusbar.set_message(_("No images in '%s'") % os.path.basename(path)) self.file_loaded = False else: self.file_loaded = True alphanumeric_sort(self._comment_files) self._window.cursor_handler.set_cursor_type(cursor.NORMAL) self._window.ui_manager.set_sensitivities() self._window.new_page() self._window.ui_manager.recent.add(path)
def open_file(self, path, start_page=1): """Open the file pointed to by <path>. If <start_page> is not set we set the current page to 1 (first page), if it is set we set the current page to the value of <start_page>. If <start_page> is non-positive it means the last image. Return True if the file is successfully loaded. """ dir_path = None # If the given <path> is invalid we update the statusbar. # (bad idea if it's permanently hidden; but no better way nearby) if not os.access(path, os.R_OK): self._window.statusbar.set_message( _('Could not open %s: Permission denied.') % path) return False if os.path.isdir(path): dir_path = path # handle it as a directory later. # likely, can also check `os.access(path, os.X_OK)` instead of # getting 'unknown type'. elif not os.path.isfile(path): # ...not dir or normal file. self._window.statusbar.set_message( _('Could not open %s: No such file.') % path) return False self.archive_type = archive.archive_mime_type(path) if self.archive_type in (None, archive.DIRECTORY,) and not is_image_file(path) and \ not dir_path: self._window.statusbar.set_message( _('Could not open %s: Unknown file type.') % path) return False # We close the previously opened file. self._window.cursor_handler.set_cursor_type(cursor.WAIT) if self.file_loaded: self.close_file() while gtk.events_pending(): gtk.main_iteration(False) unknown_files = [] # If <path> is an archive we create an Extractor for it and set the # files in it with file endings indicating image files or comments # as the ones to be extracted. if self.archive_type not in ( None, archive.DIRECTORY, ): self._base_path = path self._condition = self._extractor.setup(path, self._tmp_dir) files = self._extractor.get_files() image_files = filter(self._image_re.search, files) alphanumeric_sort(image_files) comment_files = filter(self._comment_re.search, files) # Allow managing sub-archives unknown_files = \ filter(lambda i: i not in image_files + comment_files, files) self._image_files = \ [os.path.join(self._tmp_dir, f) for f in image_files] self._comment_files = \ [os.path.join(self._tmp_dir, f) for f in comment_files] for name, full_path in zip(image_files, self._image_files): self._name_table[full_path] = name for name, full_path in zip(comment_files, self._comment_files): self._name_table[full_path] = name for name in unknown_files: self._name_table[self._tmp_dir + name] = name self._redo_priority_ordering(start_page, image_files) self._extractor.extract() else: # If <path> is an image we scan its directory for more (or for # any at all if <path> is directory). self._base_path = dir_path if dir_path else os.path.dirname(path) # Not necessary to sort *all* of it, but whatever. for r, d, fls in os.walk(self._base_path): for f in fls: fpath = os.path.join(r, f) if is_image_file(fpath): self._image_files.append(fpath) self._name_table[fpath] = f alphanumeric_sort(self._image_files) if dir_path: self._redo_priority_ordering(start_page, self._image_files) else: self._current_image_index = self._image_files.index(path) # Manage subarchive if unknown_files: has_subarchive = False for (i, name) in enumerate(unknown_files): f = self._tmp_dir + name self._wait_on_file(f) if archive.archive_mime_type(f) not in ( None, archive.DIRECTORY, ): self._open_subarchive(os.path.dirname(f), os.path.basename(f)) has_subarchive = True # Allows to avoid any behaviour changes if there was no subarchive.. if has_subarchive: # Now, get all files, and move them into the temp directory # while renaming them to avoid any sorting error. self._image_files = [] tmpdir_len = len(self._tmp_dir) extracted_files = [] for file in get_next_file(self._tmp_dir): dst = file[tmpdir_len:].replace("/", "_") extracted_files.append(dst) dst = self._tmp_dir + dst shutil.move(file, dst) self._image_files.append(dst) self._comment_files = \ filter(self._comment_re.search, self._image_files) self._image_files = \ filter(self._image_re.search, self._image_files) alphanumeric_sort(self._image_files) self._name_table.clear() for full_path in self._image_files + self._comment_files: self._name_table[full_path] = os.path.basename(full_path) self._extractor.set_files(extracted_files, True) #redo calculation of current_index from start_page self._redo_priority_ordering(start_page, self._image_files) if not self._image_files: self._window.statusbar.set_message( _("No images or subarchives in '%s'") % os.path.basename(path)) self.file_loaded = False else: self.file_loaded = True alphanumeric_sort(self._comment_files) self._window.cursor_handler.set_cursor_type(cursor.NORMAL) self._window.ui_manager.set_sensitivities() self._window.new_page() self._window.ui_manager.recent.add(path)
def open_file(self, path, start_page=1): """Open the file pointed to by <path>. If <start_page> is not set we set the current page to 1 (first page), if it is set we set the current page to the value of <start_page>. If <start_page> is non-positive it means the last image. Return True if the file is successfully loaded. """ dir_path = None # If the given <path> is invalid we update the statusbar. # (bad idea if it's permanently hidden; but no better way nearby) if not os.access(path, os.R_OK): self._window.statusbar.set_message( _('Could not open %s: Permission denied.') % path) return False if os.path.isdir(path): dir_path = path # handle it as a directory later. # likely, can also check `os.access(path, os.X_OK)` instead of # getting 'unknown type'. elif not os.path.isfile(path): # ...not dir or normal file. self._window.statusbar.set_message( _('Could not open %s: No such file.') % path) return False self.archive_type = archive.archive_mime_type(path) if self.archive_type is None and not is_image_file(path) and \ not dir_path: self._window.statusbar.set_message( _('Could not open %s: Unknown file type.') % path) return False # We close the previously opened file. self._window.cursor_handler.set_cursor_type(cursor.WAIT) if self.file_loaded: self.close_file() while gtk.events_pending(): gtk.main_iteration(False) unknown_files = [] # If <path> is an archive we create an Extractor for it and set the # files in it with file endings indicating image files or comments # as the ones to be extracted. if self.archive_type is not None: self._base_path = path self._condition = self._extractor.setup(path, self._tmp_dir) files = self._extractor.get_files() image_files = filter(self._image_re.search, files) alphanumeric_sort(image_files) comment_files = filter(self._comment_re.search, files) # Allow managing sub-archives unknown_files = \ filter(lambda i: i not in image_files + comment_files, files) self._image_files = \ [os.path.join(self._tmp_dir, f) for f in image_files] self._comment_files = \ [os.path.join(self._tmp_dir, f) for f in comment_files] for name, full_path in zip(image_files, self._image_files): self._name_table[full_path] = name for name, full_path in zip(comment_files, self._comment_files): self._name_table[full_path] = name for name in unknown_files: self._name_table[self._tmp_dir + name] = name self._redo_priority_ordering(start_page, image_files) self._extractor.extract() else: # If <path> is an image we scan its directory for more (or for # any at all if <path> is directory). self._base_path = dir_path if dir_path else os.path.dirname(path) # Not necessary to sort *all* of it, but whatever. for f in list_dir_sorted(self._base_path): fpath = os.path.join(self._base_path, f) if is_image_file(fpath): self._image_files.append(fpath) if dir_path: self._redo_priority_ordering(start_page, self._image_files) else: self._current_image_index = self._image_files.index(path) # Manage subarchive if unknown_files: has_subarchive = False for (i, name) in enumerate(unknown_files): f = self._tmp_dir + name self._wait_on_file(f) if archive.archive_mime_type(f) is not None: self._open_subarchive(os.path.dirname(f), os.path.basename(f)) has_subarchive = True # Allows to avoid any behaviour changes if there was no subarchive.. if has_subarchive: # Now, get all files, and move them into the temp directory # while renaming them to avoid any sorting error. self._image_files = [] tmpdir_len = len(self._tmp_dir) extracted_files = [] for file in get_next_file(self._tmp_dir): dst = file[tmpdir_len:].replace("/", "_") extracted_files.append(dst) dst = self._tmp_dir + dst shutil.move(file, dst) self._image_files.append(dst) self._comment_files = \ filter(self._comment_re.search, self._image_files) self._image_files = \ filter(self._image_re.search, self._image_files) alphanumeric_sort(self._image_files) self._name_table.clear() for full_path in self._image_files + self._comment_files: self._name_table[full_path] = os.path.basename(full_path) self._extractor.set_files(extracted_files, True) #redo calculation of current_index from start_page self._redo_priority_ordering(start_page, self._image_files) if not self._image_files: self._window.statusbar.set_message(_("No images or subarchives in '%s'") % os.path.basename(path)) self.file_loaded = False else: self.file_loaded = True alphanumeric_sort(self._comment_files) self._window.cursor_handler.set_cursor_type(cursor.NORMAL) self._window.ui_manager.set_sensitivities() self._window.new_page() self._window.ui_manager.recent.add(path)