def _create_thumbnail_pixbuf(self, filepath): """ Creates a thumbnail pixbuf from <filepath>, and returns it as a tuple along with a file metadata dictionary: (pixbuf, tEXt_data) """ if archive_tools.archive_mime_type(filepath) is not None: extractor = archive_extractor.Extractor() tmpdir = tempfile.mkdtemp(prefix=u'mcomix_archive_thumb.') condition = extractor.setup(filepath, tmpdir) files = extractor.get_files() wanted = self._guess_cover(files) if wanted: extractor.set_files([wanted]) extractor.extract() image_path = os.path.join(tmpdir, wanted) condition.acquire() while not extractor.is_ready(wanted): condition.wait() condition.release() if not os.path.isfile(image_path): return None, None pixbuf = image_tools.load_pixbuf_size(image_path, self.width, self.height) tEXt_data = self._get_text_data(image_path) # Use the archive's mTime instead of the extracted file's mtime tEXt_data['tEXt::Thumb::MTime'] = str(long(os.stat(filepath).st_mtime)) shutil.rmtree(tmpdir, True) return pixbuf, tEXt_data else: # Then check for subarchives by file extension and # extract only the first... subs = filter(constants.SUPPORTED_ARCHIVE_REGEX.search, files) if subs: extractor.set_files([subs[0]]) extractor.extract() condition.acquire() while not extractor.is_ready(subs[0]): condition.wait() condition.release() subpath = os.path.join(tmpdir, subs[0]) # Recursively try to find an image to use as cover return self._create_thumbnail_pixbuf(subpath) shutil.rmtree(tmpdir, True) return None, None elif image_tools.is_image_file(filepath): pixbuf = image_tools.load_pixbuf_size(filepath, self.width, self.height) tEXt_data = self._get_text_data(filepath) return pixbuf, tEXt_data else: return None, None
def _create_thumbnail_pixbuf(self, filepath): """ Creates a thumbnail pixbuf from <filepath>, and returns it as a tuple along with a file metadata dictionary: (pixbuf, tEXt_data) """ if self.archive_support: mime = archive_tools.archive_mime_type(filepath) else: mime = None if mime is not None: cleanup = [] try: tmpdir = tempfile.mkdtemp(prefix=u'mcomix_archive_thumb.') cleanup.append(lambda: shutil.rmtree(tmpdir, True)) archive = archive_tools.get_recursive_archive_handler( filepath, tmpdir, type=mime) if archive is None: return None, None cleanup.append(archive.close) files = archive.list_contents() wanted = self._guess_cover(files) if wanted is None: return None, None archive.extract(wanted, tmpdir) image_path = os.path.join(tmpdir, wanted) if not os.path.isfile(image_path): return None, None pixbuf = image_tools.load_pixbuf_size(image_path, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(image_path) # Use the archive's mTime instead of the extracted file's mtime tEXt_data['tEXt::Thumb::MTime'] = str( long(os.stat(filepath).st_mtime)) else: tEXt_data = None return pixbuf, tEXt_data finally: for fn in reversed(cleanup): fn() elif image_tools.is_image_file(filepath): pixbuf = image_tools.load_pixbuf_size(filepath, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(filepath) else: tEXt_data = None return pixbuf, tEXt_data else: return None, None
def _create_thumbnail_pixbuf(self, filepath): """ Creates a thumbnail pixbuf from <filepath>, and returns it as a tuple along with a file metadata dictionary: (pixbuf, tEXt_data) """ if self.archive_support: mime = archive_tools.archive_mime_type(filepath) else: mime = None if mime is not None: cleanup = [] try: tmpdir = tempfile.mkdtemp(prefix=u'mcomix_archive_thumb.') cleanup.append(lambda: shutil.rmtree(tmpdir, True)) archive = archive_tools.get_recursive_archive_handler(filepath, tmpdir, type=mime) if archive is None: return None, None cleanup.append(archive.close) files = archive.list_contents() wanted = self._guess_cover(files) if wanted is None: return None, None archive.extract(wanted, tmpdir) image_path = os.path.join(tmpdir, wanted) if not os.path.isfile(image_path): return None, None pixbuf = image_tools.load_pixbuf_size(image_path, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(image_path) # Use the archive's mTime instead of the extracted file's mtime tEXt_data['tEXt::Thumb::MTime'] = str(long(os.stat(filepath).st_mtime)) else: tEXt_data = None return pixbuf, tEXt_data finally: for fn in reversed(cleanup): fn() elif image_tools.is_image_file(filepath): pixbuf = image_tools.load_pixbuf_size(filepath, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(filepath) else: tEXt_data = None return pixbuf, tEXt_data else: return None, None
def open_file(self, path, start_page=0, keep_fileprovider=False): '''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. ''' self._close() try: path = self._initialize_fileprovider(path, keep_fileprovider) except ValueError as ex: self._window.statusbar.set_message(str(ex)) self._window.osd.show(str(ex)) return False error_message = self._check_access(path) if error_message: self._window.statusbar.set_message(error_message) self._window.osd.show(error_message) self.file_opened() return False self.filelist = self._file_provider.list_files() self.archive_type = archive_tools.archive_mime_type(path) self._start_page = start_page self._current_file = os.path.abspath(path) self._stop_waiting = False image_files = [] current_image_index = 0 # Actually open the file(s)/archive passed in path. if self.archive_type is not None: try: self._open_archive(self._current_file) except Exception as ex: self._window.statusbar.set_message(str(ex)) self._window.osd.show(str(ex)) self.file_opened() return False self.file_loading = True else: image_files, current_image_index = \ self._open_image_files(self.filelist, self._current_file) self._archive_opened(image_files) return True
def _create_thumbnail_pixbuf(self, filepath): ''' Creates a thumbnail pixbuf from <filepath>, and returns it as a tuple along with a file metadata dictionary: (pixbuf, tEXt_data) ''' if self.archive_support: mime = archive_tools.archive_mime_type(filepath) else: mime = None if mime is not None: if not archive_tools.is_archive_file(filepath): return None, None with archive_tools.get_recursive_archive_handler( filepath, type=mime, prefix='mcomix_archive_thumb.') as archive: if archive is None: return None, None if archive.is_encrypted: image_path = tools.pkg_path('images', 'encrypted-book.png') else: files = archive.list_contents(decrypt=False) wanted = self._guess_cover(files) if wanted is None: return None, None image_path = archive.extract(wanted) if not os.path.isfile(image_path): return None, None pixbuf = image_tools.load_pixbuf_size(image_path, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(image_path) # Use the archive's mTime instead of the extracted file's mtime tEXt_data['tEXt::Thumb::MTime'] = str( os.stat(filepath).st_mtime) else: tEXt_data = None return pixbuf, tEXt_data elif image_tools.is_image_file(filepath, check_mimetype=True): pixbuf = image_tools.load_pixbuf_size(filepath, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(filepath) else: tEXt_data = None return pixbuf, tEXt_data else: return None, None
def _create_thumbnail_pixbuf(self, filepath): """ Creates a thumbnail pixbuf from <filepath>, and returns it as a tuple along with a file metadata dictionary: (pixbuf, tEXt_data) """ if self.archive_support: mime = archive_tools.archive_mime_type(filepath) else: mime = None if mime is not None: with tempfile.TemporaryDirectory( prefix='mcomix_archive_thumb.') as tmpdir: archive = archive_tools.get_recursive_archive_handler( filepath, tmpdir, type=mime) if archive is None: return None, None files = archive.list_contents() wanted = self._guess_cover(files) if wanted is None: return None, None archive.extract(wanted, tmpdir) image_path = os.path.join(tmpdir, wanted) if not os.path.isfile(image_path): return None, None pixbuf = image_tools.load_pixbuf_size(image_path, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(image_path) # Use the archive's mTime instead of the extracted file's mtime tEXt_data['tEXt::Thumb::MTime'] = str( os.stat(filepath).st_mtime) else: tEXt_data = None return pixbuf, tEXt_data elif image_tools.is_image_file(filepath): pixbuf = image_tools.load_pixbuf_size(filepath, self.width, self.height) if self.store_on_disk: tEXt_data = self._get_text_data(filepath) else: tEXt_data = None return pixbuf, tEXt_data else: return None, None
def test_archive_mime_type(self): dir = get_testfile_path('archives') for filename in os.listdir(dir): ext = '.'.join(filename.split('.')[1:]) path = os.path.join(dir, filename) archive_type = archive_tools.archive_mime_type(path) expected_type = _EXTENSION_TO_MIME_TYPES[ext] msg = ( 'archive_mime_type("%s") failed; ' 'result differs: %s [%s] instead of %s [%s]' % (path, archive_type, _ARCHIVE_TYPE_NAMES.get(archive_type, '???'), expected_type, _ARCHIVE_TYPE_NAMES.get(expected_type, '???'), ) ) self.assertEqual(archive_type, expected_type, msg=msg)
def test_archive_mime_type(self): dir = get_testfile_path('archives') for filename in os.listdir(dir): ext = '.'.join(filename.split('.')[1:]) path = os.path.join(dir, filename) archive_type = archive_tools.archive_mime_type(path) expected_type = _EXTENSION_TO_MIME_TYPES.get(ext, '???') msg = ( 'archive_mime_type("%s") failed; ' 'result differs: %s [%s] instead of %s [%s]' % (path, archive_type, _ARCHIVE_TYPE_NAMES.get(archive_type, '???'), expected_type, _ARCHIVE_TYPE_NAMES.get(expected_type, '???'), ) ) self.assertEqual(archive_type, expected_type, msg=msg)
def set_directory(self, file_or_directory): """ Sets the base directory. """ if os.path.isdir(file_or_directory): self.base_dir = os.path.abspath(file_or_directory) self.mode = OrderedFileProvider.IMAGES elif os.path.isfile(file_or_directory): self.base_dir = os.path.abspath(os.path.dirname(file_or_directory)) if image_tools.is_image_file(file_or_directory): self.mode = OrderedFileProvider.IMAGES elif archive_tools.archive_mime_type(file_or_directory) is not None: self.mode = OrderedFileProvider.ARCHIVES else: self.mode = OrderedFileProvider.IMAGES else: # Passed file doesn't exist raise ValueError(_("Invalid path: '%s'") % file_or_directory)
def set_directory(self, file_or_directory): """ Sets the base directory. """ if os.path.isdir(file_or_directory): self.base_dir = os.path.abspath(file_or_directory) self.mode = OrderedFileProvider.IMAGES elif os.path.isfile(file_or_directory): self.base_dir = os.path.abspath(os.path.dirname(file_or_directory)) if image_tools.is_image_file(file_or_directory): self.mode = OrderedFileProvider.IMAGES elif archive_tools.archive_mime_type( file_or_directory) is not None: self.mode = OrderedFileProvider.ARCHIVES else: self.mode = OrderedFileProvider.IMAGES else: # Passed file doesn't exist raise ValueError(_("Invalid path: '%s'") % file_or_directory)
def _open_previous_archive(self, *args): """Open the archive that comes directly before the currently loaded archive in that archive's directory listing, sorted alphabetically. Returns True if a new archive was opened, False otherwise. """ if self.archive_type is not None: files = self._file_provider.list_files(file_provider.FileProvider.ARCHIVES) absolute_path = os.path.abspath(self._base_path) if absolute_path not in files: return current_index = files.index(absolute_path) for path in reversed(files[:current_index]): if archive_tools.archive_mime_type(path) is not None: self._close() self.open_file(path, -1, keep_fileprovider=True) return True return False
def _open_next_archive(self, *args): """Open the archive that comes directly after the currently loaded archive in that archive's directory listing, sorted alphabetically. Returns True if a new archive was opened, False otherwise. """ if self.archive_type is not None: files = self._file_provider.list_files(file_provider.FileProvider.ARCHIVES) absolute_path = os.path.abspath(self._base_path) if absolute_path not in files: return current_index = files.index(absolute_path) for path in files[current_index + 1:]: if archive_tools.archive_mime_type(path) is not None: self.close_file() self._window.imagehandler.close() self._window.scroll_to_fixed(horiz='startfirst', vert='top') self.open_file(path, keep_fileprovider=True) return True return False
def setup(self, src, dst, type=None): """Setup the extractor with archive <src> and destination dir <dst>. Return a threading.Condition related to the is_ready() method, or None if the format of <src> isn't supported. """ self._src = src self._dst = dst self._type = type or archive_tools.archive_mime_type(src) self._files = [] self._extracted = {} self._stop = False self._extract_thread = None self._condition = threading.Condition() self._archive = archive_tools.get_archive_handler(src) if self._archive: self._files = self._archive.list_contents() self._setupped = True return self._condition else: msg = _('Non-supported archive format: %s') % os.path.basename(src) log.warning(msg) raise ArchiveException(msg)
class FileHandler(object): """The FileHandler keeps track of the actual files/archives opened. While ImageHandler takes care of pages/images, this class provides the raw file names for archive members and image files, extracts archives, and lists directories for image files. """ def __init__(self, window): #: Indicates if files/archives are currently loaded/loading. self.file_loaded = False self.file_loading = False #: None if current file is not an archive, or unrecognized format. self.archive_type = None #: Either path to the current archive, or first file in image list. #: This is B{not} the path to the currently open page. self._current_file = None #: Reference to L{MainWindow}. self._window = window #: Path to opened archive file, or directory containing current images. self._base_path = None #: Temporary directory used for extracting archives. self._tmp_dir = None #: If C{True}, no longer wait for files to get extracted. self._stop_waiting = False #: List of comment files inside of the currently opened archive. self._comment_files = [] #: Mapping of absolute paths to archive path names. self._name_table = {} #: Archive extractor. self._extractor = archive_extractor.Extractor() self._extractor.file_extracted += self._extracted_file self._extractor.contents_listed += self._listed_contents #: Condition to wait on when extracting archives and waiting on files. self._condition = None #: Provides a list of available files/archives in the open directory. self._file_provider = None #: Keeps track of the last read page in archives self.last_read_page = last_read_page.LastReadPage( backend.LibraryBackend()) #: Regexp used for determining which archive files are images. self._image_re = image_tools.SUPPORTED_IMAGE_REGEX #: Regexp used for determining which archive files are comment files. self._comment_re = None self.update_comment_extensions() self.last_read_page.set_enabled(bool(prefs['store recent file info'])) def refresh_file(self, *args, **kwargs): """ Closes the current file(s)/archive and reloads them. """ if self.file_loaded: current_file = os.path.abspath( self._window.imagehandler.get_real_path()) if self.archive_type is not None: start_page = self._window.imagehandler.get_current_page() else: start_page = 0 self.open_file(current_file, start_page, keep_fileprovider=True) def open_file(self, path, start_page=0, keep_fileprovider=False): """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. """ self._close() try: path = self._initialize_fileprovider(path, keep_fileprovider) except ValueError, ex: self._window.statusbar.set_message(unicode(ex)) self._window.osd.show(unicode(ex)) return False error_message = self._check_access(path) if error_message: self._window.statusbar.set_message(error_message) self._window.osd.show(error_message) self.file_opened() return False self.filelist = self._file_provider.list_files() self.archive_type = archive_tools.archive_mime_type(path) self._start_page = start_page self._current_file = os.path.abspath(path) self._stop_waiting = False image_files = [] current_image_index = 0 # Actually open the file(s)/archive passed in path. if self.archive_type is not None: try: self._open_archive(self._current_file) except Exception, ex: self._window.statusbar.set_message(unicode(ex)) self._window.osd.show(unicode(ex)) self.file_opened() return False self.file_loading = True
def _open_archive(self, path, start_page): """ Opens the archive passed in C{path}. Creates an L{archive_extractor.Extractor} and extracts all images found within the archive. @return: A tuple containing C{(image_files, image_index)}. """ self._base_path = path try: self._condition = self._extractor.setup(self._base_path, self._tmp_dir, self.archive_type) except Exception: self._condition = None raise if self._condition != None: files = self._extractor.get_files() archive_images = [image for image in files if self._image_re.search(image) # Remove MacOS meta files from image list and not u'__MACOSX' in os.path.normpath(image).split(os.sep)] tools.alphanumeric_sort(archive_images) image_files = [ os.path.join(self._tmp_dir, f) for f in archive_images ] comment_files = filter(self._comment_re.search, files) self._comment_files = [ os.path.join(self._tmp_dir, f) for f in comment_files ] # Allow managing sub-archives by keeping archives based on extension archive_files = filter(constants.SUPPORTED_ARCHIVE_REGEX.search, files) archive_files_paths = [ os.path.join(self._tmp_dir, f) for f in archive_files ] for name, full_path in zip(archive_images, 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, full_path in zip(archive_files, archive_files_paths): self._name_table[full_path] = name # Determine current archive image index. current_image_index = self._get_index_for_page(start_page, len(image_files), path) # Sort files to determine extraction order. self._sort_archive_files(archive_images, current_image_index) self._extractor.set_files(archive_images + comment_files + archive_files) self._extractor.file_extracted += self._extracted_file self._extractor.extract() # Manage subarchive through recursion if archive_files: has_subarchive = False # For each potential archive, change the current extractor, # extract recursively, and restore the internal extractor. for f in archive_files_paths: if not self._extractor.is_ready(f): self._wait_on_file(f) if archive_tools.archive_mime_type(f) is not None: # save self data state = self._save_state() # Setup temporary data self._extractor = archive_extractor.Extractor() self._tmp_dir = os.path.join(self._tmp_dir, os.path.basename(f) + u'.dir') if not os.path.exists(self._tmp_dir): os.mkdir(self._tmp_dir) self._condition = self._extractor.setup(self._base_path, self._tmp_dir, self.archive_type) self._extractor.file_extracted += self._extracted_file add_images, dummy_idx = self._open_archive(f, 1) # recursion here # Since it's recursive, we do not want to loose the way to ensure # that the file was extracted, so too bad but it will be a lil' slower. for image in add_images: self._wait_on_file(image) image_files.extend(add_images) self._extractor.stop() self._extractor.close() # restore self data self._restore_state(state) has_subarchive = True # Allows to avoid any behaviour changes if there was no subarchive.. if has_subarchive: # Mark additional files as extracted self._comment_files = \ filter(self._comment_re.search, image_files) tmp_image_files = \ filter(self._image_re.search, image_files) self._name_table.clear() for full_path in tmp_image_files + self._comment_files: self._name_table[full_path] = os.path.basename(full_path) # This trick here allows to avoid indefinite waiting on # the sub-extracted files. self._extractor._extracted[os.path.basename(full_path)] = True # set those files instead of image_files for the return image_files = tmp_image_files # Image index may have changed after additional files were extracted. current_image_index = self._get_index_for_page(start_page, len(image_files), path) return image_files, current_image_index else: # No condition was returned from the Extractor, i.e. invalid archive. return [], 0
class FileHandler(object): """The FileHandler keeps track of the actual files/archives opened. While ImageHandler takes care of pages/images, this class provides the raw file names for archive members and image files, extracts archives, and lists directories for image files. """ def __init__(self, window): #: Indicates if files/archives are currently loaded. self.file_loaded = False #: None if current file is not an archive, or unrecognized format. self.archive_type = None #: Either path to the current archive, or first file in image list. #: This is B{not} the path to the currently open page. self._current_file = None #: Reference to L{MainWindow}. self._window = window #: Path to opened archive file, or directory containing current images. self._base_path = None #: Temporary directory used for extracting archives. self._tmp_dir = tempfile.mkdtemp(prefix=u'mcomix.', suffix=os.sep) #: If C{True}, no longer wait for files to get extracted. self._stop_waiting = False #: List of comment files inside of the currently opened archive. self._comment_files = [] #: Mapping of absolute paths to archive path names. self._name_table = {} #: Archive extractor. self._extractor = archive_extractor.Extractor() #: Condition to wait on when extracting archives and waiting on files. self._condition = None #: Provides a list of available files/archives in the open directory. self._file_provider = None #: Keeps track of the last read page in archives self.last_read_page = last_read_page.LastReadPage(constants.LASTPAGE_DATABASE_PATH) #: Regexp used for determining which archive files are images. self._image_re = constants.SUPPORTED_IMAGE_REGEX #: Regexp used for determining which archive files are comment files. self._comment_re = None self.update_comment_extensions() self.last_read_page.set_enabled( prefs['store recent file info'] == constants.STORE_LAST_PATH_AND_PAGE) def refresh_file(self, *args, **kwargs): """ Closes the current file(s)/archive and reloads them. """ if self.file_loaded: current_file = os.path.abspath(self._window.imagehandler.get_real_path()) self.open_file(current_file, keep_fileprovider=True) def open_file(self, path, start_page=0, keep_fileprovider=False): """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. """ try: path = self._initialize_fileprovider(path, keep_fileprovider) except ValueError, ex: self._window.statusbar.set_message(unicode(ex)) self._window.osd.show(unicode(ex)) return False if os.path.exists(path) and os.access(path, os.R_OK): filelist = self._file_provider.list_files() archive_type = archive_tools.archive_mime_type(path) else: filelist = [] archive_type = None error_message = self._check_for_error_message(path, filelist, archive_type) if error_message: self._window.statusbar.set_message(error_message) self._window.osd.show(error_message) return False # We close the previously opened file. if self.file_loaded: self.close_file() # Catch up on UI events before actually starting to open the file(s). while gtk.events_pending(): gtk.main_iteration(False) self.archive_type = archive_type self._current_file = os.path.abspath(path) self._stop_waiting = False result = False image_files = [] current_image_index = 0 # Actually open the file(s)/archive passed in path. if self.archive_type is not None: try: image_files, current_image_index = \ self._open_archive(self._current_file, start_page) except Exception, ex: self.file_loaded = False self._window.statusbar.set_message(unicode(ex)) self._window.osd.show(unicode(ex)) self._window.uimanager.set_sensitivities() return False # Update status bar archive_list = self._file_provider.list_files( file_provider.FileProvider.ARCHIVES) if self._current_file in archive_list: current_index = archive_list.index(self._current_file) else: current_index = 0 self._window.statusbar.set_file_number(current_index + 1, len(archive_list))
class FileHandler(object): """The FileHandler keeps track of the actual files/archives opened. While ImageHandler takes care of pages/images, this class provides the raw file names for archive members and image files, extracts archives, and lists directories for image files. """ def __init__(self, window): #: Indicates if files/archives are currently loaded/loading. self.file_loaded = False self.file_loading = False #: None if current file is not an archive, or unrecognized format. self.archive_type = None self._to_delete = {} self._did_split = False #: Either path to the current archive, or first file in image list. #: This is B{not} the path to the currently open page. self._current_file = None #: Reference to L{MainWindow}. self._window = window #: Path to opened archive file, or directory containing current images. self._base_path = None #: Temporary directory used for extracting archives. self._tmp_dir = None #: If C{True}, no longer wait for files to get extracted. self._stop_waiting = False #: List of comment files inside of the currently opened archive. self._comment_files = [] #: Mapping of absolute paths to archive path names. self._name_table = {} #: Archive extractor. self._extractor = archive_extractor.Extractor() self._extractor.file_extracted += self._extracted_file self._extractor.contents_listed += self._listed_contents #: Condition to wait on when extracting archives and waiting on files. self._condition = None #: Provides a list of available files/archives in the open directory. self._file_provider = None #: Keeps track of the last read page in archives self.last_read_page = last_read_page.LastReadPage( backend.LibraryBackend()) #: Regexp used for determining which archive files are images. self._image_re = image_tools.SUPPORTED_IMAGE_REGEX #: Regexp used for determining which archive files are comment files. self._comment_re = None self.update_comment_extensions() self.last_read_page.set_enabled(bool(prefs['store recent file info'])) def refresh_file(self, *args, **kwargs): """ Closes the current file(s)/archive and reloads them. """ if self.file_loaded: current_file = os.path.abspath( self._window.imagehandler.get_real_path()) if self.archive_type is not None: start_page = self._window.imagehandler.get_current_page() else: start_page = 0 self.open_file(current_file, start_page, keep_fileprovider=True) def delete_file(self, archive_file_name): if archive_file_name in self._to_delete and self._to_delete[ archive_file_name]: print "undeleting %s" % (archive_file_name) self._to_delete[archive_file_name] = False return False else: print "deleting %s" % (archive_file_name) self._to_delete[archive_file_name] = True return True def should_split_images(self): return not self._did_split def split_images(self): if self._did_split: print "Already split, yo" return # NOTE: this can happen on startup if len(self._name_table) == 0: return self._did_split = True filenames = [k for k in self._name_table] # TODO: hyper unreliable exe_name = os.path.join(os.path.dirname(sys.argv[0]), "bins", "comic_splitter") if not os.path.exists(exe_name): print base + " doesn't exist!" return print(exe_name) output_dirname = os.path.dirname(filenames[0]) # print filenames print "Splitting at %s..." % (output_dirname) subprocess.call([exe_name, "-output", output_dirname, "-delete"] + filenames) # prefix = os.path.basename(output_dirname) # prefix = os.path.basename(output_dirname) # print prefix prefix = output_dirname files = [ os.path.join(prefix, f) for f in os.listdir(output_dirname) if os.path.isfile(os.path.join(output_dirname, f)) ] archive_images = [ image for image in files if self._image_re.search(image) # Remove MacOS meta files from image list and not u'__MACOSX' in os.path.normpath(image).split(os.sep) ] self._sort_archive_images(archive_images) image_files = [os.path.join(self._tmp_dir, f) for f in archive_images] comment_files = filter(self._comment_re.search, files) tools.alphanumeric_sort(comment_files) self._comment_files = [ os.path.join(self._tmp_dir, f) for f in comment_files ] self._name_table = dict(zip(files, archive_images)) self._name_table.update(zip(self._comment_files, comment_files)) # self.file_available(self.filelist, True) self._archive_opened(image_files) self.filelist = files self._window.imagehandler._available_images = set( range(0, len(image_files))) self._window.imagehandler._image_files = image_files # self._extractor.set_files(archive_images + comment_files) return True def _actually_delete_files(self): to_delete = [ path for (path, value) in self._to_delete.items() if value ] print "actually deleting %d files..." % (len(to_delete)) # TODO: ask if the user actually wants to delete those files if len(to_delete) > 0: to_delete_str = " ".join(["\"%s\"" % (path) for path in to_delete]) os.system("zip \"%s\" --delete %s" % (self.get_current_file(), to_delete_str)) self._to_delete.clear() def open_file(self, path, start_page=0, keep_fileprovider=False): """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. """ self._close() try: path = self._initialize_fileprovider(path, keep_fileprovider) except ValueError, ex: self._window.statusbar.set_message(unicode(ex)) self._window.osd.show(unicode(ex)) return False error_message = self._check_access(path) if error_message: self._window.statusbar.set_message(error_message) self._window.osd.show(error_message) self.file_opened() return False self.filelist = self._file_provider.list_files() self.archive_type = archive_tools.archive_mime_type(path) self._start_page = start_page self._current_file = os.path.abspath(path) self._stop_waiting = False image_files = [] current_image_index = 0 # Actually open the file(s)/archive passed in path. if self.archive_type is not None: try: self._open_archive(self._current_file) except Exception, ex: self._window.statusbar.set_message(unicode(ex)) self._window.osd.show(unicode(ex)) self.file_opened() return False self.file_loading = True