- use imghdr module to determine filetype instead of extension

- (The imghdr module is in the standard library,
     so this creates no extra dependency.)
- store filenames in unicode internally
  - got rid of QString and QStringList
  - got rid of unicodize
- fix crash if directory didn't end with slash
- added time.sleep(0.1) before quit inside Worker.run
  to avoid a segfault when no images were processed
  (For example an empty directory was passed to trimage)
  (This segfault was present even before I touched anything)
  (A better "fix" would be not even initializing the GUI when
   there is no need)
This commit is contained in:
Kálmán Tarnay 2010-03-29 04:11:05 +02:00
parent a506c0fee4
commit 1862f6f019

View file

@ -10,6 +10,7 @@ from optparse import OptionParser
from PyQt4.QtCore import * from PyQt4.QtCore import *
from PyQt4.QtGui import * from PyQt4.QtGui import *
from hurry.filesize import * from hurry.filesize import *
from imghdr import what as determinetype
from ui import Ui_trimage from ui import Ui_trimage
@ -82,9 +83,9 @@ class StartQT4(QMainWindow):
# send to correct function # send to correct function
if options.filename: if options.filename:
self.file_from_cmd(options.filename) self.file_from_cmd(options.filename.decode("utf-8"))
if options.directory: if options.directory:
self.dir_from_cmd(options.directory) self.dir_from_cmd(options.directory.decode("utf-8"))
self.verbose = options.verbose self.verbose = options.verbose
@ -97,12 +98,12 @@ class StartQT4(QMainWindow):
Read the files in the directory and send all files to compress_file. Read the files in the directory and send all files to compress_file.
""" """
self.showapp = False self.showapp = False
dirpath = path.abspath(path.dirname(directory)) dirpath = path.abspath(directory)
imagedir = listdir(directory) imagedir = listdir(directory)
filelist = QStringList() filelist = []
for image in imagedir: for image in imagedir:
image = self.unicodize(path.join(dirpath, image)) image = path.join(dirpath, image)
if self.checkname(image): if path.isfile(image) and self.checkname(image):
filelist.append(image) filelist.append(image)
self.delegator(filelist) self.delegator(filelist)
@ -110,17 +111,15 @@ class StartQT4(QMainWindow):
"""Get the file and send it to compress_file""" """Get the file and send it to compress_file"""
self.showapp = False self.showapp = False
image = path.abspath(image) image = path.abspath(image)
filecmdlist = QStringList() filecmdlist = []
if self.checkname(image): if self.checkname(image):
filecmdlist.append(self.unicodize(image)) filecmdlist.append(image)
self.delegator(filecmdlist) self.delegator(filecmdlist)
def file_drop(self, images): def file_drop(self, images):
""" """
Get a file from the drag and drop handler and send it to compress_file. Get a file from the drag and drop handler and send it to compress_file.
""" """
for image in images:
image = self.unicodize(unicode(image).encode('utf-8'))
self.delegator(images) self.delegator(images)
def file_dialog(self): def file_dialog(self):
@ -132,9 +131,6 @@ class StartQT4(QMainWindow):
# this is a fix for file dialog differentiating between cases # this is a fix for file dialog differentiating between cases
"Image files (*.png *.jpg *.jpeg *.PNG *.JPG *.JPEG)") "Image files (*.png *.jpg *.jpeg *.PNG *.JPG *.JPEG)")
for image in images:
image = self.unicodize(unicode(image))
self.delegator(images) self.delegator(images)
def recompress_files(self): def recompress_files(self):
@ -204,7 +200,7 @@ class StartQT4(QMainWindow):
def checkname(self, name): def checkname(self, name):
"""Check if the file is a jpg or png.""" """Check if the file is a jpg or png."""
return path.splitext(unicode(name))[1].lower() in [".jpg", ".jpeg", ".png"] return determinetype(name) in ["jpeg", "png"]
def enable_recompress(self): def enable_recompress(self):
"""Enable the recompress button.""" """Enable the recompress button."""
@ -239,13 +235,6 @@ class StartQT4(QMainWindow):
else: else:
raise raise
def unicodize(self, obj, encoding='utf-8'):
if isinstance(obj, basestring):
if not isinstance(obj, unicode):
obj = unicode(obj, encoding)
return obj
class TriTableModel(QAbstractTableModel): class TriTableModel(QAbstractTableModel):
def __init__(self, parent, imagelist, header, *args): def __init__(self, parent, imagelist, header, *args):
@ -310,19 +299,18 @@ class Worker(QThread):
"""Compress the given file, get data from it and call update_table.""" """Compress the given file, get data from it and call update_table."""
for image in self.images: for image in self.images:
#gather old file data #gather old file data
filename = unicode(image[0]) filename = image[0]
icon = image[1] icon = image[1]
oldfile = QFileInfo(filename) oldfile = QFileInfo(filename)
name = oldfile.fileName() name = oldfile.fileName()
oldfilesize = oldfile.size() oldfilesize = oldfile.size()
oldfilesizestr = size(oldfilesize, system=alternative) oldfilesizestr = size(oldfilesize, system=alternative)
# get extention filetype = determinetype(filename)
extention = path.splitext(filename)[1] #decide which tool to use
#decide with tool to use if filetype is "jpeg":
if extention in [".jpg", ".jpeg"]:
runString = u"jpegoptim -f --strip-all '%(file)s'" runString = u"jpegoptim -f --strip-all '%(file)s'"
elif extention in [".png"]: elif filetype is "png":
runString = (u"optipng -force -o7 '%(file)s'; advpng -z4 '%(file)s'") runString = (u"optipng -force -o7 '%(file)s'; advpng -z4 '%(file)s'")
else: else:
sys.stderr.write("[error] %s not an image file" % filename) sys.stderr.write("[error] %s not an image file" % filename)
@ -362,6 +350,13 @@ class Worker(QThread):
sys.stderr.write("[error] %s" % runfile) sys.stderr.write("[error] %s" % runfile)
if not self.showapp: if not self.showapp:
# A little sleep to avoid segfault...
# If you pass an empty directory(-d) to trimage,
# python segfaults when you call quit here.
if len(self.images)==0:
import time
time.sleep(0.1)
#make sure the app quits after all images are done #make sure the app quits after all images are done
quit() quit()
@ -384,6 +379,7 @@ class TrimageTableView(QTableView):
files = str(event.mimeData().data("text/uri-list")).strip().split() files = str(event.mimeData().data("text/uri-list")).strip().split()
for i, file in enumerate(files): for i, file in enumerate(files):
files[i] = QUrl(QString(file)).toLocalFile() files[i] = QUrl(QString(file)).toLocalFile()
files=[i.toUtf8().decode("utf-8") for i in files]
self.emit(SIGNAL("fileDropEvent"), (files)) self.emit(SIGNAL("fileDropEvent"), (files))
if __name__ == "__main__": if __name__ == "__main__":