from os.path import basename, dirname from sys import argv, exit from os import getcwd from PyQt4.QtCore import SIGNAL from PyQt4.QtCore import Qt from PyQt4.QtGui import (QApplication, QDialog, QTableWidgetItem, QFileDialog, QMessageBox) from hachoir.metadata.qt.dialog_ui import Ui_Form from hachoir.core import config from hachoir.core.error import HACHOIR_ERRORS from hachoir.core.cmd_line import unicodeFilename from hachoir.parser import createParser from hachoir.metadata import extractMetadata from hachoir.metadata.metadata import MultipleMetadata config.quiet = True class CustomTableWidgetItem(QTableWidgetItem): def __init__(self, parent=None): super(CustomTableWidgetItem, self).__init__(parent) self.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) class MetadataError(Exception): def __init__(self, message): self.unicode_message = message bytes_message = message.encode("ASCII", "replace") Exception.__init__(self, bytes_message) def __unicode__(self): return self.unicode_message class File: def __init__(self, filename, realname): self.name = filename if realname: self.realname = realname else: self.realname = filename try: self.parser = createParser(self.name, self.realname) except HACHOIR_ERRORS as err: raise MetadataError("Parser error: %s" % str(err)) if not self.parser: raise MetadataError("Unable to parse the file: %s" % self.name) try: self.metadata = extractMetadata(self.parser) except HACHOIR_ERRORS as err: raise MetadataError("Metadata extraction error: %s" % str(err)) if not self.metadata: file_type = self.parser.mime_type raise MetadataError( "Unable to extract metadata from file of type %s" % file_type) class Metadata(QDialog, Ui_Form): def __init__(self, application): QDialog.__init__(self) self.application = application self.files = {} self.setupWindow() self.current_dir = dirname(getcwd()) def setupWindow(self): self.setupUi(self) self.connect(self.open_button, SIGNAL("clicked()"), self.open) self.connect(self.quit_button, SIGNAL("clicked()"), self.quit) self.connect( self.files_combo, SIGNAL("currentIndexChanged(const QString&)"), self.changeFile) self.metadata_table.horizontalHeader().hide() self.metadata_table.verticalHeader().hide() def open(self): filename = QFileDialog.getOpenFileName( self, # parent "Choose a file to open", # caption self.current_dir, # dir name "", # filter "Any type" # filter set ) if not filename: return filename = str(filename) self.current_dir = dirname(filename) self.addFile(filename, change=True) def quit(self): self.application.quit() def fillList(self, file): table = self.metadata_table metadata = file.metadata groups = [metadata] if isinstance(metadata, MultipleMetadata): groups.extend(list(metadata.iterGroups())) total = 0 for index, metadata in enumerate(groups): group_name = metadata.header metadata = [data for data in metadata if data.values] metadata.sort() if 0 < index: metadata.insert(0, group_name) groups[index] = metadata total += len(metadata) table.clear() table.setColumnCount(2) table.setRowCount(total) row = 0 for metadata in groups: for data in metadata: if isinstance(data, str): table.setItem(row, 0, CustomTableWidgetItem("-- group --")) table.setItem(row, 1, CustomTableWidgetItem(data)) row += 1 continue title = data.description for item in data.values: value = item.text table.setItem(row, 0, CustomTableWidgetItem(title)) table.setItem(row, 1, CustomTableWidgetItem(value)) row += 1 table.resizeColumnsToContents() def changeFile(self, name): name = str(name) file = self.files[name] self.fillList(file) def error(self, message): QMessageBox.warning(self, "Metadata error", message) def addFile(self, filename, realname=None, change=False): try: file = File(filename, realname) except MetadataError as err: errmsg = str(err) self.error(errmsg) return name = basename(file.name) self.files[name] = file self.files_combo.addItem(name) if change: index = self.files_combo.count() - 1 self.files_combo.setCurrentIndex(index) def main(): app = QApplication(argv) metadata = Metadata(app) for filename in argv[1:]: realname = filename filename = unicodeFilename(filename) metadata.addFile(filename, realname) metadata.show() exitcode = app.exec_() exit(exitcode)