def __init__(self, parent, mode, expand_on_click=True): super(CoverImageWidget, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('coverimagewidget.ui'), self) reduceWidgetFontSize(self.label) self.mode = mode self.comicVine = ComicVineTalker() self.page_loader = None self.showControls = True self.btnLeft.setIcon(QIcon(ComicTaggerSettings.getGraphic('left.png'))) self.btnRight.setIcon( QIcon(ComicTaggerSettings.getGraphic('right.png'))) self.btnLeft.clicked.connect(self.decrementImage) self.btnRight.clicked.connect(self.incrementImage) self.resetWidget() if expand_on_click: clickable(self.lblImage).connect(self.showPopup) else: self.lblImage.setToolTip("") self.updateContent()
def __init__(self, parent, image_pixmap): super(ImagePopup, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('imagepopup.ui' ), self) QtGui.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.WaitCursor)) #self.setWindowModality(QtCore.Qt.WindowModal) self.setWindowFlags(QtCore.Qt.Popup) self.setWindowState(QtCore.Qt.WindowFullScreen) self.imagePixmap = image_pixmap screen_size = QtGui.QDesktopWidget().screenGeometry() self.resize(screen_size.width(), screen_size.height()) self.move( 0, 0) # This is a total hack. Uses a snapshot of the desktop, and overlays a # translucent screen over it. Probably can do it better by setting opacity of a # widget self.desktopBg = QtGui.QPixmap.grabWindow(QtGui.QApplication.desktop ().winId(), 0,0, screen_size.width(), screen_size.height()) bg = QtGui.QPixmap(ComicTaggerSettings.getGraphic('popup_bg.png')) self.clientBgPixmap = bg.scaled(screen_size.width(), screen_size.height()) self.setMask(self.clientBgPixmap.mask()) self.applyImagePixmap() self.showFullScreen() self.raise_( ) QtGui.QApplication.restoreOverrideCursor()
def __init__(self, parent, metadata): super(PageBrowserWindow, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('pagebrowser.ui' ), self) self.pageWidget = CoverImageWidget( self.pageContainer, CoverImageWidget.ArchiveMode ) gridlayout = QtGui.QGridLayout( self.pageContainer ) gridlayout.addWidget( self.pageWidget ) gridlayout.setContentsMargins(0,0,0,0) self.pageWidget.showControls = False self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowMaximizeButtonHint) self.comic_archive = None self.page_count = 0 self.current_page_num = 0 self.metadata = metadata self.buttonBox.button(QtGui.QDialogButtonBox.Close).setDefault(True) if platform.system() == "Darwin": self.btnPrev.setText("<<") self.btnNext.setText(">>") else: self.btnPrev.setIcon(QtGui.QIcon( ComicTaggerSettings.getGraphic('left.png' ))) self.btnNext.setIcon(QtGui.QIcon( ComicTaggerSettings.getGraphic('right.png'))) self.btnNext.clicked.connect( self.nextPage ) self.btnPrev.clicked.connect( self.prevPage ) self.show() self.btnNext.setEnabled( False ) self.btnPrev.setEnabled( False )
def __init__(self, parent, image_pixmap): super(ImagePopup, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('imagepopup.ui'), self) QtGui.QApplication.setOverrideCursor( QtGui.QCursor(QtCore.Qt.WaitCursor)) # self.setWindowModality(QtCore.Qt.WindowModal) self.setWindowFlags(QtCore.Qt.Popup) self.setWindowState(QtCore.Qt.WindowFullScreen) self.imagePixmap = image_pixmap screen_size = QtGui.QDesktopWidget().screenGeometry() self.resize(screen_size.width(), screen_size.height()) self.move(0, 0) # This is a total hack. Uses a snapshot of the desktop, and overlays a # translucent screen over it. Probably can do it better by setting opacity of a # widget self.desktopBg = QtGui.QPixmap.grabWindow( QtGui.QApplication.desktop().winId(), 0, 0, screen_size.width(), screen_size.height()) bg = QtGui.QPixmap(ComicTaggerSettings.getGraphic('popup_bg.png')) self.clientBgPixmap = bg.scaled(screen_size.width(), screen_size.height()) self.setMask(self.clientBgPixmap.mask()) self.applyImagePixmap() self.showFullScreen() self.raise_() QtGui.QApplication.restoreOverrideCursor()
def ctmain(): utils.fix_output_encoding() settings = ComicTaggerSettings() opts = Options() opts.parseCmdLineArgs() # manage the CV API key if opts.cv_api_key: if opts.cv_api_key != settings.cv_api_key: settings.cv_api_key = opts.cv_api_key settings.save() if opts.only_set_key: print("Key set") return ComicVineTalker.api_key = settings.cv_api_key signal.signal(signal.SIGINT, signal.SIG_DFL) if not qt_available and not opts.no_gui: opts.no_gui = True print >> sys.stderr, "PyQt4 is not available. ComicTagger is limited to command-line mode." if opts.no_gui: cli.cli_mode(opts, settings) else: app = QtGui.QApplication(sys.argv) if platform.system() != "Linux": img = QtGui.QPixmap(ComicTaggerSettings.getGraphic('tags.png')) splash = QtGui.QSplashScreen(img) splash.show() splash.raise_() app.processEvents() try: tagger_window = TaggerWindow(opts.file_list, settings, opts=opts) tagger_window.show() if platform.system() != "Linux": splash.finish(tagger_window) sys.exit(app.exec_()) except Exception as e: QtGui.QMessageBox.critical( QtGui.QMainWindow(), "Error", "Unhandled exception in app:\n" + traceback.format_exc())
def ctmain(): utils.fix_output_encoding() settings = ComicTaggerSettings() opts = Options() opts.parseCmdLineArgs() # manage the CV API key if opts.cv_api_key: if opts.cv_api_key != settings.cv_api_key: settings.cv_api_key = opts.cv_api_key #settings.save() if opts.only_set_key: print("Key set") return ComicVineTalker.api_key = settings.cv_api_key signal.signal(signal.SIGINT, signal.SIG_DFL) if not qt_available and not opts.no_gui: opts.no_gui = True print >> sys.stderr, "PyQt4 is not available. ComicTagger is limited to command-line mode." if opts.no_gui: cli.cli_mode(opts, settings) else: app = QtGui.QApplication(sys.argv) if platform.system() != "Linux": img = QtGui.QPixmap(ComicTaggerSettings.getGraphic('tags.png')) splash = QtGui.QSplashScreen(img) splash.show() splash.raise_() app.processEvents() try: tagger_window = TaggerWindow(opts.file_list, settings, opts=opts) tagger_window.show() if platform.system() != "Linux": splash.finish(tagger_window) sys.exit(app.exec_()) except Exception as e: QtGui.QMessageBox.critical( QtGui.QMainWindow(), "Error", "Unhandled exception in app:\n" + traceback.format_exc())
def display_match_set_for_choice(label, match_set, opts, settings): print(u"{0} -- {1}:".format(match_set.filename, label)) # sort match list by year match_set.matches.sort(key=lambda k: k['year']) for (counter, m) in enumerate(match_set.matches): counter += 1 print(u" {0}. {1} #{2} [{3}] ({4}/{5}) - {6}".format( counter, m['series'], m['issue_number'], m['publisher'], m['month'], m['year'], m['issue_title'])) if opts.interactive: while True: i = raw_input("Choose a match #, or 's' to skip: ") if (i.isdigit() and int(i) in range( 1, len(match_set.matches) + 1)) or i == 's': break if i != 's': i = int(i) - 1 # save the data! # we know at this point, that the file is all good to go ca = ComicArchive(match_set.filename, settings.rar_exe_path, ComicTaggerSettings.getGraphic('nocover.png')) md = create_local_metadata(opts, ca, ca.hasMetadata(opts.data_style)) cv_md = actual_issue_data_fetch(match_set.matches[int(i)], settings, opts) md.overlay(cv_md) actual_metadata_save(ca, opts, md)
def __init__(self, parent , settings ): super(FileSelectionList, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('fileselectionlist.ui' ), self) self.settings = settings utils.reduceWidgetFontSize( self.twList ) self.twList.currentItemChanged.connect( self.currentItemChangedCB ) self.currentItem = None self.setContextMenuPolicy(Qt.ActionsContextMenu) self.modifiedFlag = False selectAllAction = QAction("Select All", self) removeAction = QAction("Remove Selected Items", self) self.separator = QAction("",self) self.separator.setSeparator(True) selectAllAction.setShortcut( 'Ctrl+A' ) removeAction.setShortcut( 'Ctrl+X' ) selectAllAction.triggered.connect(self.selectAll) removeAction.triggered.connect(self.removeSelection) self.addAction(selectAllAction) self.addAction(removeAction) self.addAction(self.separator)
def __init__(self, parent, settings ): super(SettingsWindow, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('settingswindow.ui' ), self) self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowContextHelpButtonHint ) self.settings = settings self.name = "Settings" if platform.system() == "Windows": self.lblUnrar.hide() self.leUnrarExePath.hide() self.btnBrowseUnrar.hide() self.lblRarHelp.setText( windowsRarHelp ) elif platform.system() == "Linux": self.lblRarHelp.setText( linuxRarHelp ) elif platform.system() == "Darwin": self.lblRarHelp.setText( macRarHelp ) self.name = "Preferences" self.setWindowTitle("ComicTagger " + self.name) self.lblDefaultSettings.setText( "Revert to default " + self.name.lower()) self.btnResetSettings.setText( "Default " + self.name) nldtTip = ( """ <html>The <b>Default Name Length Match Tolerance</b> is for eliminating automatic search matches that are too long compared to your series name search. The higher it is, the more likely to have a good match, but each search will take longer and use more bandwidth. Too low, and only the very closest lexical matches will be explored.</html>""" ) self.leNameLengthDeltaThresh.setToolTip(nldtTip) pblTip = ( """<html> The <b>Publisher Blacklist</b> is for eliminating automatic matches to certain publishers that you know are incorrect. Useful for avoiding international re-prints with same covers or series names. Enter publisher names separated by commas. </html>""" ) self.tePublisherBlacklist.setToolTip(pblTip) validator = QtGui.QIntValidator(1, 4, self) self.leIssueNumPadding.setValidator(validator) validator = QtGui.QIntValidator(0, 99, self) self.leNameLengthDeltaThresh.setValidator(validator) self.settingsToForm() self.btnBrowseRar.clicked.connect(self.selectRar) self.btnBrowseUnrar.clicked.connect(self.selectUnrar) self.btnClearCache.clicked.connect(self.clearCache) self.btnResetSettings.clicked.connect(self.resetSettings) self.btnTestKey.clicked.connect(self.testAPIKey)
def __init__(self, parent): super(AutoTagProgressWindow, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('autotagprogresswindow.ui'), self) self.archiveCoverWidget = CoverImageWidget(self.archiveCoverContainer, CoverImageWidget.DataMode, False) gridlayout = QtGui.QGridLayout(self.archiveCoverContainer) gridlayout.addWidget(self.archiveCoverWidget) gridlayout.setContentsMargins(0, 0, 0, 0) self.testCoverWidget = CoverImageWidget(self.testCoverContainer, CoverImageWidget.DataMode, False) gridlayout = QtGui.QGridLayout(self.testCoverContainer) gridlayout.addWidget(self.testCoverWidget) gridlayout.setContentsMargins(0, 0, 0, 0) self.isdone = False self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowMaximizeButtonHint) utils.reduceWidgetFontSize(self.textEdit)
def __init__(self, parent, matches, comic_archive): super(MatchSelectionWindow, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('matchselectionwindow.ui' ), self) self.altCoverWidget = CoverImageWidget( self.altCoverContainer, CoverImageWidget.AltCoverMode ) gridlayout = QtGui.QGridLayout( self.altCoverContainer ) gridlayout.addWidget( self.altCoverWidget ) gridlayout.setContentsMargins(0,0,0,0) self.archiveCoverWidget = CoverImageWidget( self.archiveCoverContainer, CoverImageWidget.ArchiveMode ) gridlayout = QtGui.QGridLayout( self.archiveCoverContainer ) gridlayout.addWidget( self.archiveCoverWidget ) gridlayout.setContentsMargins(0,0,0,0) utils.reduceWidgetFontSize( self.twList ) utils.reduceWidgetFontSize( self.teDescription, 1 ) self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowMaximizeButtonHint) self.matches = matches self.comic_archive = comic_archive self.twList.currentItemChanged.connect(self.currentItemChanged) self.twList.cellDoubleClicked.connect(self.cellDoubleClicked) self.updateData()
def __init__(self, parent ): super(PageListEditor, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('pagelisteditor.ui' ), self) self.pageWidget = CoverImageWidget( self.pageContainer, CoverImageWidget.ArchiveMode ) gridlayout = QGridLayout( self.pageContainer ) gridlayout.addWidget( self.pageWidget ) gridlayout.setContentsMargins(0,0,0,0) self.pageWidget.showControls = False self.resetPage() # Add the entries to the manga combobox self.comboBox.addItem( "", "" ) self.comboBox.addItem( self.pageTypeNames[ PageType.FrontCover], PageType.FrontCover ) self.comboBox.addItem( self.pageTypeNames[ PageType.InnerCover], PageType.InnerCover ) self.comboBox.addItem( self.pageTypeNames[ PageType.Advertisment], PageType.Advertisment ) self.comboBox.addItem( self.pageTypeNames[ PageType.Roundup], PageType.Roundup ) self.comboBox.addItem( self.pageTypeNames[ PageType.Story], PageType.Story ) self.comboBox.addItem( self.pageTypeNames[ PageType.Editorial], PageType.Editorial ) self.comboBox.addItem( self.pageTypeNames[ PageType.Letters], PageType.Letters ) self.comboBox.addItem( self.pageTypeNames[ PageType.Preview], PageType.Preview ) self.comboBox.addItem( self.pageTypeNames[ PageType.BackCover], PageType.BackCover ) self.comboBox.addItem( self.pageTypeNames[ PageType.Other], PageType.Other ) self.comboBox.addItem( self.pageTypeNames[ PageType.Deleted], PageType.Deleted ) self.listWidget.itemSelectionChanged.connect( self.changePage ) itemMoveEvents(self.listWidget).connect(self.itemMoveEvent) self.comboBox.activated.connect( self.changePageType ) self.btnUp.clicked.connect( self.moveCurrentUp ) self.btnDown.clicked.connect( self.moveCurrentDown ) self.pre_move_row = -1 self.first_front_page = None
def __init__(self, parent, settings): super(FileSelectionList, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('fileselectionlist.ui'), self) self.settings = settings reduceWidgetFontSize(self.twList) self.twList.setColumnCount(6) #self.twlist.setHorizontalHeaderLabels (["File", "Folder", "CR", "CBL", ""]) # self.twList.horizontalHeader().setStretchLastSection(True) self.twList.currentItemChanged.connect(self.currentItemChangedCB) self.currentItem = None self.setContextMenuPolicy(Qt.ActionsContextMenu) self.modifiedFlag = False selectAllAction = QAction("Select All", self) removeAction = QAction("Remove Selected Items", self) self.separator = QAction("", self) self.separator.setSeparator(True) selectAllAction.setShortcut('Ctrl+A') removeAction.setShortcut('Ctrl+X') selectAllAction.triggered.connect(self.selectAll) removeAction.triggered.connect(self.removeSelection) self.addAction(selectAllAction) self.addAction(removeAction) self.addAction(self.separator)
def __init__(self, parent, matches, comic_archive): super(MatchSelectionWindow, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('matchselectionwindow.ui'), self) self.altCoverWidget = CoverImageWidget(self.altCoverContainer, CoverImageWidget.AltCoverMode) gridlayout = QtGui.QGridLayout(self.altCoverContainer) gridlayout.addWidget(self.altCoverWidget) gridlayout.setContentsMargins(0, 0, 0, 0) self.archiveCoverWidget = CoverImageWidget( self.archiveCoverContainer, CoverImageWidget.ArchiveMode) gridlayout = QtGui.QGridLayout(self.archiveCoverContainer) gridlayout.addWidget(self.archiveCoverWidget) gridlayout.setContentsMargins(0, 0, 0, 0) utils.reduceWidgetFontSize(self.twList) utils.reduceWidgetFontSize(self.teDescription, 1) self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowMaximizeButtonHint) self.matches = matches self.comic_archive = comic_archive self.twList.currentItemChanged.connect(self.currentItemChanged) self.twList.cellDoubleClicked.connect(self.cellDoubleClicked) self.updateData()
def __init__(self, parent, settings): super(FileSelectionList, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('fileselectionlist.ui'), self) self.settings = settings utils.reduceWidgetFontSize(self.twList) self.twList.currentItemChanged.connect(self.currentItemChangedCB) self.currentItem = None self.setContextMenuPolicy(Qt.ActionsContextMenu) self.modifiedFlag = False selectAllAction = QAction("Select All", self) removeAction = QAction("Remove Selected Items", self) self.separator = QAction("", self) self.separator.setSeparator(True) selectAllAction.setShortcut('Ctrl+A') removeAction.setShortcut('Ctrl+X') selectAllAction.triggered.connect(self.selectAll) removeAction.triggered.connect(self.removeSelection) self.addAction(selectAllAction) self.addAction(removeAction) self.addAction(self.separator)
def __init__(self, parent): super(AutoTagProgressWindow, self).__init__(parent) uic.loadUi( ComicTaggerSettings.getUIFile('autotagprogresswindow.ui'), self) self.archiveCoverWidget = CoverImageWidget( self.archiveCoverContainer, CoverImageWidget.DataMode, False) gridlayout = QtGui.QGridLayout(self.archiveCoverContainer) gridlayout.addWidget(self.archiveCoverWidget) gridlayout.setContentsMargins(0, 0, 0, 0) self.testCoverWidget = CoverImageWidget( self.testCoverContainer, CoverImageWidget.DataMode, False) gridlayout = QtGui.QGridLayout(self.testCoverContainer) gridlayout.addWidget(self.testCoverWidget) gridlayout.setContentsMargins(0, 0, 0, 0) self.isdone = False self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowMaximizeButtonHint) reduceWidgetFontSize(self.textEdit)
def __init__(self, path, rar_exe_path=None): self.path = path self.rar_exe_path = rar_exe_path self.ci_xml_filename = 'ComicInfo.xml' self.comet_default_filename = 'CoMet.xml' self.resetCache() if self.rarTest(): self.archive_type = self.ArchiveType.Rar self.archiver = RarArchiver(self.path, rar_exe_path=self.rar_exe_path) elif self.zipTest(): self.archive_type = self.ArchiveType.Zip self.archiver = ZipArchiver(self.path) elif os.path.isdir(self.path): self.archive_type = self.ArchiveType.Folder self.archiver = FolderArchiver(self.path) else: self.archive_type = self.ArchiveType.Unknown self.archiver = UnknownArchiver(self.path) if ComicArchive.logo_data is None: fname = ComicTaggerSettings.getGraphic('nocover.png') with open(fname, 'rb') as fd: ComicArchive.logo_data = fd.read()
def __init__( self, path, settings ): self.path = path self.ci_xml_filename = 'ComicInfo.xml' self.comet_default_filename = 'CoMet.xml' self.resetCache() self.settings = settings if self.zipTest(): self.archive_type = self.ArchiveType.Zip self.archiver = ZipArchiver( self.path ) elif self.rarTest(): self.archive_type = self.ArchiveType.Rar self.archiver = RarArchiver( self.path, settings ) elif os.path.isdir( self.path ): self.archive_type = self.ArchiveType.Folder self.archiver = FolderArchiver( self.path ) else: self.archive_type = self.ArchiveType.Unknown self.archiver = UnknownArchiver( self.path ) if ComicArchive.logo_data is None: fname = ComicTaggerSettings.getGraphic('nocover.png') with open(fname, 'rb') as fd: ComicArchive.logo_data = fd.read()
def __init__(self, parent): super(LogWindow, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('logwindow.ui'), self) self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowMaximizeButtonHint)
def __init__(self, parent): super(LogWindow, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('logwindow.ui' ), self) self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowMaximizeButtonHint)
def __init__(self, parent, settings): super(SettingsWindow, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('settingswindow.ui'), self) self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowContextHelpButtonHint) self.settings = settings self.name = "Settings" if platform.system() == "Windows": self.lblUnrar.hide() self.leUnrarExePath.hide() self.btnBrowseUnrar.hide() self.lblRarHelp.setText(windowsRarHelp) elif platform.system() == "Linux": self.lblRarHelp.setText(linuxRarHelp) elif platform.system() == "Darwin": self.lblRarHelp.setText(macRarHelp) self.name = "Preferences" self.setWindowTitle("ComicTagger " + self.name) self.lblDefaultSettings.setText("Revert to default " + self.name.lower()) self.btnResetSettings.setText("Default " + self.name) nldtTip = ( """<html>The <b>Default Name Length Match Tolerance</b> is for eliminating automatic search matches that are too long compared to your series name search. The higher it is, the more likely to have a good match, but each search will take longer and use more bandwidth. Too low, and only the very closest lexical matches will be explored.</html>""") self.leNameLengthDeltaThresh.setToolTip(nldtTip) pblTip = ("""<html> The <b>Publisher Blacklist</b> is for eliminating automatic matches to certain publishers that you know are incorrect. Useful for avoiding international re-prints with same covers or series names. Enter publisher names separated by commas. </html>""") self.tePublisherBlacklist.setToolTip(pblTip) validator = QtGui.QIntValidator(1, 4, self) self.leIssueNumPadding.setValidator(validator) validator = QtGui.QIntValidator(0, 99, self) self.leNameLengthDeltaThresh.setValidator(validator) self.settingsToForm() self.btnBrowseRar.clicked.connect(self.selectRar) self.btnBrowseUnrar.clicked.connect(self.selectUnrar) self.btnClearCache.clicked.connect(self.clearCache) self.btnResetSettings.clicked.connect(self.resetSettings) self.btnTestKey.clicked.connect(self.testAPIKey)
def __init__(self, parent): super(IDProgressWindow, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('progresswindow.ui'), self) self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowMaximizeButtonHint) utils.reduceWidgetFontSize(self.textEdit)
def __init__(self): QObject.__init__(self) self.settings_folder = ComicTaggerSettings.getSettingsFolder() self.db_file = os.path.join(self.settings_folder, "image_url_cache.db") self.cache_folder = os.path.join(self.settings_folder, "image_cache") if not os.path.exists(self.db_file): self.create_image_db()
def __init__(self ): QObject.__init__(self) self.settings_folder = ComicTaggerSettings.getSettingsFolder() self.db_file = os.path.join( self.settings_folder, "image_url_cache.db" ) self.cache_folder = os.path.join( self.settings_folder, "image_cache" ) if not os.path.exists( self.db_file ): self.create_image_db()
def __init__(self, parent): super(IDProgressWindow, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('progresswindow.ui'), self) self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowMaximizeButtonHint) reduceWidgetFontSize(self.textEdit)
def addPathItem(self, path): path = unicode(path) path = os.path.abspath(path) # print "processing", path if self.isListDupe(path): return self.getCurrentListRow(path) ca = ComicArchive( path, self.settings.rar_exe_path, ComicTaggerSettings.getGraphic('nocover.png')) if ca.seemsToBeAComicArchive(): row = self.twList.rowCount() self.twList.insertRow(row) fi = FileInfo(ca) filename_item = QTableWidgetItem() folder_item = QTableWidgetItem() cix_item = FileTableWidgetItem() cbi_item = FileTableWidgetItem() readonly_item = FileTableWidgetItem() type_item = QTableWidgetItem() filename_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) filename_item.setData(Qt.UserRole, fi) self.twList.setItem( row, FileSelectionList.fileColNum, filename_item) folder_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) self.twList.setItem( row, FileSelectionList.folderColNum, folder_item) type_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) self.twList.setItem(row, FileSelectionList.typeColNum, type_item) cix_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) cix_item.setTextAlignment(Qt.AlignHCenter) self.twList.setItem(row, FileSelectionList.CRFlagColNum, cix_item) cbi_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) cbi_item.setTextAlignment(Qt.AlignHCenter) self.twList.setItem(row, FileSelectionList.CBLFlagColNum, cbi_item) readonly_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) readonly_item.setTextAlignment(Qt.AlignHCenter) self.twList.setItem( row, FileSelectionList.readonlyColNum, readonly_item) self.updateRow(row) return row
def addPathItem(self, path): path = unicode(path) path = os.path.abspath(path) # print "processing", path if self.isListDupe(path): return self.getCurrentListRow(path) ca = ComicArchive(path, self.settings.rar_exe_path, ComicTaggerSettings.getGraphic('nocover.png')) if ca.seemsToBeAComicArchive(): row = self.twList.rowCount() self.twList.insertRow(row) fi = FileInfo(ca) filename_item = QTableWidgetItem() folder_item = QTableWidgetItem() cix_item = FileTableWidgetItem() cbi_item = FileTableWidgetItem() readonly_item = FileTableWidgetItem() type_item = QTableWidgetItem() filename_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) filename_item.setData(Qt.UserRole, fi) self.twList.setItem(row, FileSelectionList.fileColNum, filename_item) folder_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) self.twList.setItem(row, FileSelectionList.folderColNum, folder_item) type_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) self.twList.setItem(row, FileSelectionList.typeColNum, type_item) cix_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) cix_item.setTextAlignment(Qt.AlignHCenter) self.twList.setItem(row, FileSelectionList.CRFlagColNum, cix_item) cbi_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) cbi_item.setTextAlignment(Qt.AlignHCenter) self.twList.setItem(row, FileSelectionList.CBLFlagColNum, cbi_item) readonly_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) readonly_item.setTextAlignment(Qt.AlignHCenter) self.twList.setItem(row, FileSelectionList.readonlyColNum, readonly_item) self.updateRow(row) return row
def __init__( self, parent, settings, msg ): super(AutoTagStartWindow, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('autotagstartwindow.ui' ), self) self.label.setText( msg ) self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowContextHelpButtonHint ) self.settings = settings self.cbxSaveOnLowConfidence.setCheckState( QtCore.Qt.Unchecked ) self.cbxDontUseYear.setCheckState( QtCore.Qt.Unchecked ) self.cbxAssumeIssueOne.setCheckState( QtCore.Qt.Unchecked ) self.cbxIgnoreLeadingDigitsInFilename.setCheckState( QtCore.Qt.Unchecked ) self.cbxRemoveAfterSuccess.setCheckState( QtCore.Qt.Unchecked ) self.cbxSpecifySearchString.setCheckState( QtCore.Qt.Unchecked ) self.leNameLengthMatchTolerance.setText( str(self.settings.id_length_delta_thresh) ) self.leSearchString.setEnabled( False ) nlmtTip = ( """ <html>The <b>Name Length Match Tolerance</b> is for eliminating automatic search matches that are too long compared to your series name search. The higher it is, the more likely to have a good match, but each search will take longer and use more bandwidth. Too low, and only the very closest lexical matches will be explored.</html>""" ) self.leNameLengthMatchTolerance.setToolTip(nlmtTip) ssTip = ( """<html> The <b>series search string</b> specifies the search string to be used for all selected archives. Use this when trying to match archives with hard-to-parse or incorrect filenames. All archives selected should be from the same series. </html>""" ) self.leSearchString.setToolTip(ssTip) self.cbxSpecifySearchString.setToolTip(ssTip) validator = QtGui.QIntValidator(0, 99, self) self.leNameLengthMatchTolerance.setValidator(validator) self.cbxSpecifySearchString.stateChanged.connect(self.searchStringToggle) self.autoSaveOnLow = False self.dontUseYear = False self.assumeIssueOne = False self.ignoreLeadingDigitsInFilename = False self.removeAfterSuccess = False self.searchString = None self.nameLengthMatchTolerance = self.settings.id_length_delta_thresh
def __init__(self, parent, series_name, issue_number, year, issue_count, cover_index_list, comic_archive, settings, autoselect=False): super(VolumeSelectionWindow, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('volumeselectionwindow.ui'), self) self.imageWidget = CoverImageWidget(self.imageContainer, CoverImageWidget.URLMode) gridlayout = QtGui.QGridLayout(self.imageContainer) gridlayout.addWidget(self.imageWidget) gridlayout.setContentsMargins(0, 0, 0, 0) reduceWidgetFontSize(self.teDetails, 1) reduceWidgetFontSize(self.twList) self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowMaximizeButtonHint) self.settings = settings self.series_name = series_name self.issue_number = issue_number self.year = year self.issue_count = issue_count self.volume_id = 0 self.comic_archive = comic_archive self.immediate_autoselect = autoselect self.cover_index_list = cover_index_list self.cv_search_results = None self.twList.resizeColumnsToContents() self.twList.currentItemChanged.connect(self.currentItemChanged) self.twList.cellDoubleClicked.connect(self.cellDoubleClicked) self.btnRequery.clicked.connect(self.requery) self.btnIssues.clicked.connect(self.showIssues) self.btnAutoSelect.clicked.connect(self.autoSelect) self.updateButtons() self.performQuery() self.twList.selectRow(0)
def __init__( self, parent, comic_archive_list, data_style, settings ): super(RenameWindow, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('renamewindow.ui' ), self) self.label.setText("Preview (based on {0} tags):".format(MetaDataStyle.name[data_style])) self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowMaximizeButtonHint) self.settings = settings self.comic_archive_list = comic_archive_list self.data_style = data_style self.btnSettings.clicked.connect( self.modifySettings ) self.configRenamer() self.doPreview()
def __init__(self, parent, settings, series_id, issue_number): super(IssueSelectionWindow, self).__init__(parent) uic.loadUi( ComicTaggerSettings.getUIFile('issueselectionwindow.ui'), self) self.coverWidget = CoverImageWidget( self.coverImageContainer, CoverImageWidget.AltCoverMode) gridlayout = QtGui.QGridLayout(self.coverImageContainer) gridlayout.addWidget(self.coverWidget) gridlayout.setContentsMargins(0, 0, 0, 0) reduceWidgetFontSize(self.twList) reduceWidgetFontSize(self.teDescription, 1) self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowMaximizeButtonHint) self.series_id = series_id self.settings = settings self.url_fetch_thread = None if issue_number is None or issue_number == "": self.issue_number = 1 else: self.issue_number = issue_number self.initial_id = None self.performQuery() self.twList.resizeColumnsToContents() self.twList.currentItemChanged.connect(self.currentItemChanged) self.twList.cellDoubleClicked.connect(self.cellDoubleClicked) # now that the list has been sorted, find the initial record, and # select it if self.initial_id is None: self.twList.selectRow(0) else: for r in range(0, self.twList.rowCount()): issue_id, b = self.twList.item( r, 0).data(QtCore.Qt.UserRole).toInt() if (issue_id == self.initial_id): self.twList.selectRow(r) break
def __init__(self, parent): super(PageListEditor, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('pagelisteditor.ui'), self) self.pageWidget = CoverImageWidget(self.pageContainer, CoverImageWidget.ArchiveMode) gridlayout = QGridLayout(self.pageContainer) gridlayout.addWidget(self.pageWidget) gridlayout.setContentsMargins(0, 0, 0, 0) self.pageWidget.showControls = False self.resetPage() # Add the entries to the manga combobox self.comboBox.addItem("", "") self.comboBox.addItem(self.pageTypeNames[PageType.FrontCover], PageType.FrontCover) self.comboBox.addItem(self.pageTypeNames[PageType.InnerCover], PageType.InnerCover) self.comboBox.addItem(self.pageTypeNames[PageType.Advertisement], PageType.Advertisement) self.comboBox.addItem(self.pageTypeNames[PageType.Roundup], PageType.Roundup) self.comboBox.addItem(self.pageTypeNames[PageType.Story], PageType.Story) self.comboBox.addItem(self.pageTypeNames[PageType.Editorial], PageType.Editorial) self.comboBox.addItem(self.pageTypeNames[PageType.Letters], PageType.Letters) self.comboBox.addItem(self.pageTypeNames[PageType.Preview], PageType.Preview) self.comboBox.addItem(self.pageTypeNames[PageType.BackCover], PageType.BackCover) self.comboBox.addItem(self.pageTypeNames[PageType.Other], PageType.Other) self.comboBox.addItem(self.pageTypeNames[PageType.Deleted], PageType.Deleted) self.listWidget.itemSelectionChanged.connect(self.changePage) itemMoveEvents(self.listWidget).connect(self.itemMoveEvent) self.comboBox.activated.connect(self.changePageType) self.btnUp.clicked.connect(self.moveCurrentUp) self.btnDown.clicked.connect(self.moveCurrentDown) self.pre_move_row = -1 self.first_front_page = None
def __init__(self, parent, comic_archive_list, data_style, settings): super(RenameWindow, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('renamewindow.ui'), self) self.label.setText("Preview (based on {0} tags):".format( MetaDataStyle.name[data_style])) self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowMaximizeButtonHint) self.settings = settings self.comic_archive_list = comic_archive_list self.data_style = data_style self.btnSettings.clicked.connect(self.modifySettings) self.configRenamer() self.doPreview()
def __init__(self, parent, settings, series_id, issue_number): super(IssueSelectionWindow, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('issueselectionwindow.ui'), self) self.coverWidget = CoverImageWidget(self.coverImageContainer, CoverImageWidget.AltCoverMode) gridlayout = QtGui.QGridLayout(self.coverImageContainer) gridlayout.addWidget(self.coverWidget) gridlayout.setContentsMargins(0, 0, 0, 0) reduceWidgetFontSize(self.twList) reduceWidgetFontSize(self.teDescription, 1) self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowMaximizeButtonHint) self.series_id = series_id self.settings = settings self.url_fetch_thread = None if issue_number is None or issue_number == "": self.issue_number = 1 else: self.issue_number = issue_number self.initial_id = None self.performQuery() self.twList.resizeColumnsToContents() self.twList.currentItemChanged.connect(self.currentItemChanged) self.twList.cellDoubleClicked.connect(self.cellDoubleClicked) # now that the list has been sorted, find the initial record, and # select it if self.initial_id is None: self.twList.selectRow(0) else: for r in range(0, self.twList.rowCount()): issue_id, b = self.twList.item(r, 0).data( QtCore.Qt.UserRole).toInt() if (issue_id == self.initial_id): self.twList.selectRow(r) break
def __init__(self, parent, settings, msg): super(ExportWindow, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('exportwindow.ui'), self) self.label.setText(msg) self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowContextHelpButtonHint) self.settings = settings self.cbxDeleteOriginal.setCheckState(QtCore.Qt.Unchecked) self.cbxAddToList.setCheckState(QtCore.Qt.Checked) self.radioDontCreate.setChecked(True) self.deleteOriginal = False self.addToList = True self.fileConflictBehavior = ExportConflictOpts.dontCreate
def __init__( self, parent, settings, msg ): super(ExportWindow, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('exportwindow.ui' ), self) self.label.setText( msg ) self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowContextHelpButtonHint ) self.settings = settings self.cbxDeleteOriginal.setCheckState( QtCore.Qt.Unchecked ) self.cbxAddToList.setCheckState( QtCore.Qt.Checked ) self.radioDontCreate.setChecked( True ) self.deleteOriginal = False self.addToList = True self.fileConflictBehavior = ExportConflictOpts.dontCreate
def __init__(self ): self.settings_folder = ComicTaggerSettings.getSettingsFolder() self.db_file = os.path.join( self.settings_folder, "cv_cache.db") self.version_file = os.path.join( self.settings_folder, "cache_version.txt") #verify that cache is from same version as this one data = "" try: with open( self.version_file, 'rb' ) as f: data = f.read() f.close() except: pass if data != ctversion.version: self.clearCache() if not os.path.exists( self.db_file ): self.create_cache_db()
def getQImageFromData(image_data): img = QtGui.QImage() success = img.loadFromData(image_data) if not success: try: if pil_available: # Qt doesn't understand the format, but maybe PIL does # so try to convert the image data to uncompressed tiff format im = Image.open(StringIO.StringIO(image_data)) output = StringIO.StringIO() im.save(output, format="TIFF") img.loadFromData(output.getvalue()) success = True except Exception as e: pass # if still nothing, go with default image if not success: img.load(ComicTaggerSettings.getGraphic('nocover.png')) return img
def getQImageFromData(image_data): img = QtGui.QImage() success = img.loadFromData( image_data ) if not success: try: if pil_available: # Qt doesn't understand the format, but maybe PIL does # so try to convert the image data to uncompressed tiff format im = Image.open(StringIO.StringIO(image_data)) output = StringIO.StringIO() im.save(output, format="TIFF") img.loadFromData( output.getvalue() ) success = True except Exception as e: pass # if still nothing, go with default image if not success: img.load(ComicTaggerSettings.getGraphic('nocover.png')) return img
def __init__(self, parent, mode, role, name, primary): super(CreditEditorWindow, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('crediteditorwindow.ui'), self) self.mode = mode if self.mode == self.ModeEdit: self.setWindowTitle("Edit Credit") else: self.setWindowTitle("New Credit") # Add the entries to the role combobox self.cbRole.addItem("") self.cbRole.addItem("Writer") self.cbRole.addItem("Artist") self.cbRole.addItem("Penciller") self.cbRole.addItem("Inker") self.cbRole.addItem("Colorist") self.cbRole.addItem("Letterer") self.cbRole.addItem("Cover Artist") self.cbRole.addItem("Editor") self.cbRole.addItem("Other") self.cbRole.addItem("Plotter") self.cbRole.addItem("Scripter") self.leName.setText(name) if role is not None and role != "": i = self.cbRole.findText(role) if i == -1: self.cbRole.setEditText(role) else: self.cbRole.setCurrentIndex(i) if primary: self.cbPrimary.setCheckState(QtCore.Qt.Checked) self.cbRole.currentIndexChanged.connect(self.roleChanged) self.cbRole.editTextChanged.connect(self.roleChanged) self.updatePrimaryButton()
def __init__(self): self.settings_folder = ComicTaggerSettings.getSettingsFolder() self.db_file = os.path.join(self.settings_folder, "cv_cache.db") self.version_file = os.path.join(self.settings_folder, "cache_version.txt") # verify that cache is from same version as this one data = "" try: with open(self.version_file, 'rb') as f: data = f.read() f.close() except: pass if data != ctversion.version: self.clearCache() if not os.path.exists(self.db_file): self.create_cache_db()
def __init__(self, parent, mode, role, name, primary): super(CreditEditorWindow, self).__init__(parent) uic.loadUi( ComicTaggerSettings.getUIFile('crediteditorwindow.ui'), self) self.mode = mode if self.mode == self.ModeEdit: self.setWindowTitle("Edit Credit") else: self.setWindowTitle("New Credit") # Add the entries to the role combobox self.cbRole.addItem("") self.cbRole.addItem("Writer") self.cbRole.addItem("Artist") self.cbRole.addItem("Penciller") self.cbRole.addItem("Inker") self.cbRole.addItem("Colorist") self.cbRole.addItem("Letterer") self.cbRole.addItem("Cover Artist") self.cbRole.addItem("Editor") self.cbRole.addItem("Other") self.cbRole.addItem("Plotter") self.cbRole.addItem("Scripter") self.leName.setText(name) if role is not None and role != "": i = self.cbRole.findText(role) if i == -1: self.cbRole.setEditText(role) else: self.cbRole.setCurrentIndex(i) if primary: self.cbPrimary.setCheckState(QtCore.Qt.Checked) self.cbRole.currentIndexChanged.connect(self.roleChanged) self.cbRole.editTextChanged.connect(self.roleChanged) self.updatePrimaryButton()
def __init__(self, parent, match_set_list, style, fetch_func): super(AutoTagMatchWindow, self).__init__(parent) uic.loadUi( ComicTaggerSettings.getUIFile('matchselectionwindow.ui'), self) self.altCoverWidget = CoverImageWidget( self.altCoverContainer, CoverImageWidget.AltCoverMode) gridlayout = QtGui.QGridLayout(self.altCoverContainer) gridlayout.addWidget(self.altCoverWidget) gridlayout.setContentsMargins(0, 0, 0, 0) self.archiveCoverWidget = CoverImageWidget( self.archiveCoverContainer, CoverImageWidget.ArchiveMode) gridlayout = QtGui.QGridLayout(self.archiveCoverContainer) gridlayout.addWidget(self.archiveCoverWidget) gridlayout.setContentsMargins(0, 0, 0, 0) reduceWidgetFontSize(self.twList) reduceWidgetFontSize(self.teDescription, 1) self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowMaximizeButtonHint) self.skipButton = QtGui.QPushButton(self.tr("Skip to Next")) self.buttonBox.addButton( self.skipButton, QtGui.QDialogButtonBox.ActionRole) self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setText( "Accept and Write Tags") self.match_set_list = match_set_list self.style = style self.fetch_func = fetch_func self.current_match_set_idx = 0 self.twList.currentItemChanged.connect(self.currentItemChanged) self.twList.cellDoubleClicked.connect(self.cellDoubleClicked) self.skipButton.clicked.connect(self.skipToNext) self.updateData()
def __init__(self, parent, series_name, issue_number, year, issue_count, cover_index_list, comic_archive, settings, autoselect=False): super(VolumeSelectionWindow, self).__init__(parent) uic.loadUi( ComicTaggerSettings.getUIFile('volumeselectionwindow.ui'), self) self.imageWidget = CoverImageWidget( self.imageContainer, CoverImageWidget.URLMode) gridlayout = QtGui.QGridLayout(self.imageContainer) gridlayout.addWidget(self.imageWidget) gridlayout.setContentsMargins(0, 0, 0, 0) reduceWidgetFontSize(self.teDetails, 1) reduceWidgetFontSize(self.twList) self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowMaximizeButtonHint) self.settings = settings self.series_name = series_name self.issue_number = issue_number self.year = year self.issue_count = issue_count self.volume_id = 0 self.comic_archive = comic_archive self.immediate_autoselect = autoselect self.cover_index_list = cover_index_list self.cv_search_results = None self.twList.resizeColumnsToContents() self.twList.currentItemChanged.connect(self.currentItemChanged) self.twList.cellDoubleClicked.connect(self.cellDoubleClicked) self.btnRequery.clicked.connect(self.requery) self.btnIssues.clicked.connect(self.showIssues) self.btnAutoSelect.clicked.connect(self.autoSelect) self.updateButtons() self.performQuery() self.twList.selectRow(0)
def __init__(self, parent, match_set_list, style, fetch_func): super(AutoTagMatchWindow, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('matchselectionwindow.ui'), self) self.altCoverWidget = CoverImageWidget(self.altCoverContainer, CoverImageWidget.AltCoverMode) gridlayout = QtGui.QGridLayout(self.altCoverContainer) gridlayout.addWidget(self.altCoverWidget) gridlayout.setContentsMargins(0, 0, 0, 0) self.archiveCoverWidget = CoverImageWidget( self.archiveCoverContainer, CoverImageWidget.ArchiveMode) gridlayout = QtGui.QGridLayout(self.archiveCoverContainer) gridlayout.addWidget(self.archiveCoverWidget) gridlayout.setContentsMargins(0, 0, 0, 0) reduceWidgetFontSize(self.twList) reduceWidgetFontSize(self.teDescription, 1) self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowMaximizeButtonHint) self.skipButton = QtGui.QPushButton(self.tr("Skip to Next")) self.buttonBox.addButton(self.skipButton, QtGui.QDialogButtonBox.ActionRole) self.buttonBox.button( QtGui.QDialogButtonBox.Ok).setText("Accept and Write Tags") self.match_set_list = match_set_list self.style = style self.fetch_func = fetch_func self.current_match_set_idx = 0 self.twList.currentItemChanged.connect(self.currentItemChanged) self.twList.cellDoubleClicked.connect(self.cellDoubleClicked) self.skipButton.clicked.connect(self.skipToNext) self.updateData()
def display_match_set_for_choice(label, match_set, opts, settings): print(u"{0} -- {1}:".format(match_set.filename, label)) # sort match list by year match_set.matches.sort(key=lambda k: k['year']) for (counter, m) in enumerate(match_set.matches): counter += 1 print( u" {0}. {1} #{2} [{3}] ({4}/{5}) - {6}".format( counter, m['series'], m['issue_number'], m['publisher'], m['month'], m['year'], m['issue_title'])) if opts.interactive: while True: i = raw_input("Choose a match #, or 's' to skip: ") if (i.isdigit() and int(i) in range( 1, len(match_set.matches) + 1)) or i == 's': break if i != 's': i = int(i) - 1 # save the data! # we know at this point, that the file is all good to go ca = ComicArchive( match_set.filename, settings.rar_exe_path, ComicTaggerSettings.getGraphic('nocover.png')) md = create_local_metadata( opts, ca, ca.hasMetadata(opts.data_style)) cv_md = actual_issue_data_fetch( match_set.matches[int(i)], settings, opts) md.overlay(cv_md) actual_metadata_save(ca, opts, md)
def loadDefault( self ): self.current_pixmap = QPixmap(ComicTaggerSettings.getGraphic('nocover.png')) #print "loadDefault called" self.setDisplayPixmap( 0, 0)
def loadDefault(self): self.current_pixmap = QPixmap( ComicTaggerSettings.getGraphic('nocover.png')) #print("loadDefault called") self.setDisplayPixmap(0, 0)
def process_file_cli(filename, opts, settings, match_results): batch_mode = len(opts.file_list) > 1 ca = ComicArchive(filename, settings.rar_exe_path, ComicTaggerSettings.getGraphic('nocover.png')) if not os.path.lexists(filename): print >> sys.stderr, "Cannot find " + filename return if not ca.seemsToBeAComicArchive(): print >> sys.stderr, "Sorry, but " + \ filename + " is not a comic archive!" return # if not ca.isWritableForStyle(opts.data_style) and (opts.delete_tags or # opts.save_tags or opts.rename_file): if not ca.isWritable() and (opts.delete_tags or opts.copy_tags or opts.save_tags or opts.rename_file): print >> sys.stderr, "This archive is not writable for that tag type" return has = [False, False, False] if ca.hasCIX(): has[MetaDataStyle.CIX] = True if ca.hasCBI(): has[MetaDataStyle.CBI] = True if ca.hasCoMet(): has[MetaDataStyle.COMET] = True if opts.print_tags: if opts.data_style is None: page_count = ca.getNumberOfPages() brief = "" if batch_mode: brief = u"{0}: ".format(filename) if ca.isZip(): brief += "ZIP archive " elif ca.isRar(): brief += "RAR archive " elif ca.isFolder(): brief += "Folder archive " brief += "({0: >3} pages)".format(page_count) brief += " tags:[ " if not (has[MetaDataStyle.CBI] or has[MetaDataStyle.CIX] or has[MetaDataStyle.COMET]): brief += "none " else: if has[MetaDataStyle.CBI]: brief += "CBL " if has[MetaDataStyle.CIX]: brief += "CR " if has[MetaDataStyle.COMET]: brief += "CoMet " brief += "]" print brief if opts.terse: return print if opts.data_style is None or opts.data_style == MetaDataStyle.CIX: if has[MetaDataStyle.CIX]: print("--------- ComicRack tags ---------") if opts.raw: print(u"{0}".format( unicode(ca.readRawCIX(), errors='ignore'))) else: print(u"{0}".format(ca.readCIX())) if opts.data_style is None or opts.data_style == MetaDataStyle.CBI: if has[MetaDataStyle.CBI]: print("------- ComicBookLover tags -------") if opts.raw: pprint(json.loads(ca.readRawCBI())) else: print(u"{0}".format(ca.readCBI())) if opts.data_style is None or opts.data_style == MetaDataStyle.COMET: if has[MetaDataStyle.COMET]: print("----------- CoMet tags -----------") if opts.raw: print(u"{0}".format(ca.readRawCoMet())) else: print(u"{0}".format(ca.readCoMet())) elif opts.delete_tags: style_name = MetaDataStyle.name[opts.data_style] if has[opts.data_style]: if not opts.dryrun: if not ca.removeMetadata(opts.data_style): print(u"{0}: Tag removal seemed to fail!".format(filename)) else: print(u"{0}: Removed {1} tags.".format( filename, style_name)) else: print(u"{0}: dry-run. {1} tags not removed".format( filename, style_name)) else: print(u"{0}: This archive doesn't have {1} tags to remove.".format( filename, style_name)) elif opts.copy_tags: dst_style_name = MetaDataStyle.name[opts.data_style] if opts.no_overwrite and has[opts.data_style]: print(u"{0}: Already has {1} tags. Not overwriting.".format( filename, dst_style_name)) return if opts.copy_source == opts.data_style: print(u"{0}: Destination and source are same: {1}. Nothing to do.". format(filename, dst_style_name)) return src_style_name = MetaDataStyle.name[opts.copy_source] if has[opts.copy_source]: if not opts.dryrun: md = ca.readMetadata(opts.copy_source) if settings.apply_cbl_transform_on_bulk_operation and opts.data_style == MetaDataStyle.CBI: md = CBLTransformer(md, settings).apply() if not ca.writeMetadata(md, opts.data_style): print(u"{0}: Tag copy seemed to fail!".format(filename)) else: print(u"{0}: Copied {1} tags to {2} .".format( filename, src_style_name, dst_style_name)) else: print(u"{0}: dry-run. {1} tags not copied".format( filename, src_style_name)) else: print(u"{0}: This archive doesn't have {1} tags to copy.".format( filename, src_style_name)) elif opts.save_tags: if opts.no_overwrite and has[opts.data_style]: print(u"{0}: Already has {1} tags. Not overwriting.".format( filename, MetaDataStyle.name[opts.data_style])) return if batch_mode: print(u"Processing {0}...".format(filename)) md = create_local_metadata(opts, ca, has[opts.data_style]) if md.issue is None or md.issue == "": if opts.assume_issue_is_one_if_not_set: md.issue = "1" # now, search online if opts.search_online: if opts.issue_id is not None: # we were given the actual ID to search with try: comicVine = ComicVineTalker() comicVine.wait_for_rate_limit = opts.wait_and_retry_on_rate_limit cv_md = comicVine.fetchIssueDataByIssueID( opts.issue_id, settings) except ComicVineTalkerException: print >> sys.stderr, "Network error while getting issue details. Save aborted" match_results.fetchDataFailures.append(filename) return if cv_md is None: print >> sys.stderr, "No match for ID {0} was found.".format( opts.issue_id) match_results.noMatches.append(filename) return if settings.apply_cbl_transform_on_cv_import: cv_md = CBLTransformer(cv_md, settings).apply() else: ii = IssueIdentifier(ca, settings) if md is None or md.isEmpty: print >> sys.stderr, "No metadata given to search online with!" match_results.noMatches.append(filename) return def myoutput(text): if opts.verbose: IssueIdentifier.defaultWriteOutput(text) # use our overlayed MD struct to search ii.setAdditionalMetadata(md) ii.onlyUseAdditionalMetaData = True ii.waitAndRetryOnRateLimit = opts.wait_and_retry_on_rate_limit ii.setOutputFunction(myoutput) ii.cover_page_index = md.getCoverPageIndexList()[0] matches = ii.search() result = ii.search_result found_match = False choices = False low_confidence = False if result == ii.ResultNoMatches: pass elif result == ii.ResultFoundMatchButBadCoverScore: low_confidence = True found_match = True elif result == ii.ResultFoundMatchButNotFirstPage: found_match = True elif result == ii.ResultMultipleMatchesWithBadImageScores: low_confidence = True choices = True elif result == ii.ResultOneGoodMatch: found_match = True elif result == ii.ResultMultipleGoodMatches: choices = True if choices: if low_confidence: print >> sys.stderr, "Online search: Multiple low confidence matches. Save aborted" match_results.lowConfidenceMatches.append( MultipleMatch(filename, matches)) return else: print >> sys.stderr, "Online search: Multiple good matches. Save aborted" match_results.multipleMatches.append( MultipleMatch(filename, matches)) return if low_confidence and opts.abortOnLowConfidence: print >> sys.stderr, "Online search: Low confidence match. Save aborted" match_results.lowConfidenceMatches.append( MultipleMatch(filename, matches)) return if not found_match: print >> sys.stderr, "Online search: No match found. Save aborted" match_results.noMatches.append(filename) return # we got here, so we have a single match # now get the particular issue data cv_md = actual_issue_data_fetch(matches[0], settings, opts) if cv_md is None: match_results.fetchDataFailures.append(filename) return md.overlay(cv_md) # ok, done building our metadata. time to save if not actual_metadata_save(ca, opts, md): match_results.writeFailures.append(filename) else: match_results.goodMatches.append(filename) elif opts.rename_file: msg_hdr = "" if batch_mode: msg_hdr = u"{0}: ".format(filename) if opts.data_style is not None: use_tags = has[opts.data_style] else: use_tags = False md = create_local_metadata(opts, ca, use_tags) if md.series is None: print >> sys.stderr, msg_hdr + "Can't rename without series name" return new_ext = None # default if settings.rename_extension_based_on_archive: if ca.isZip(): new_ext = ".cbz" elif ca.isRar(): new_ext = ".cbr" renamer = FileRenamer(md) renamer.setTemplate(settings.rename_template) renamer.setIssueZeroPadding(settings.rename_issue_number_padding) renamer.setSmartCleanup(settings.rename_use_smart_string_cleanup) new_name = renamer.determineName(filename, ext=new_ext) if new_name == os.path.basename(filename): print >> sys.stderr, msg_hdr + "Filename is already good!" return folder = os.path.dirname(os.path.abspath(filename)) new_abs_path = utils.unique_file(os.path.join(folder, new_name)) suffix = "" if not opts.dryrun: # rename the file os.rename(filename, new_abs_path) else: suffix = " (dry-run, no change)" print(u"renamed '{0}' -> '{1}' {2}".format(os.path.basename(filename), new_name, suffix)) elif opts.export_to_zip: msg_hdr = "" if batch_mode: msg_hdr = u"{0}: ".format(filename) if not ca.isRar(): print >> sys.stderr, msg_hdr + "Archive is not a RAR." return rar_file = os.path.abspath(os.path.abspath(filename)) new_file = os.path.splitext(rar_file)[0] + ".cbz" if opts.abort_export_on_conflict and os.path.lexists(new_file): print msg_hdr + "{0} already exists in the that folder.".format( os.path.split(new_file)[1]) return new_file = utils.unique_file(os.path.join(new_file)) delete_success = False export_success = False if not opts.dryrun: if ca.exportAsZip(new_file): export_success = True if opts.delete_rar_after_export: try: os.unlink(rar_file) except: print >> sys.stderr, msg_hdr + \ "Error deleting original RAR after export" delete_success = False else: delete_success = True else: # last export failed, so remove the zip, if it exists if os.path.lexists(new_file): os.remove(new_file) else: msg = msg_hdr + \ u"Dry-run: Would try to create {0}".format( os.path.split(new_file)[1]) if opts.delete_rar_after_export: msg += u" and delete orginal." print(msg) return msg = msg_hdr if export_success: msg += u"Archive exported successfully to: {0}".format( os.path.split(new_file)[1]) if opts.delete_rar_after_export and delete_success: msg += u" (Original deleted) " else: msg += u"Archive failed to export!" print(msg)
def emit(a, b, c): pass import ctversion import utils from comicvinecacher import ComicVineCacher from genericmetadata import GenericMetadata from issuestring import IssueString from settings import ComicTaggerSettings try: import requests except: try: lib_path = os.path.join(ComicTaggerSettings.baseDir(), '..') sys.path.append(lib_path) import requests except ImportError: print "Unable to use requests module. This is a CRITICAL error and ComicTagger cannot proceed. Exiting." class CVTypeID: Volume = "4050" Issue = "4000" class ComicVineTalkerException(Exception): Unknown = -1 Network = -2 InvalidKey = 100 RateLimit = 107
def __init__(self, parent, settings, msg): super(AutoTagStartWindow, self).__init__(parent) uic.loadUi(ComicTaggerSettings.getUIFile('autotagstartwindow.ui'), self) self.label.setText(msg) self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowContextHelpButtonHint) self.settings = settings self.cbxSaveOnLowConfidence.setCheckState(QtCore.Qt.Unchecked) self.cbxDontUseYear.setCheckState(QtCore.Qt.Unchecked) self.cbxAssumeIssueOne.setCheckState(QtCore.Qt.Unchecked) self.cbxIgnoreLeadingDigitsInFilename.setCheckState( QtCore.Qt.Unchecked) self.cbxRemoveAfterSuccess.setCheckState(QtCore.Qt.Unchecked) self.cbxSpecifySearchString.setCheckState(QtCore.Qt.Unchecked) self.leNameLengthMatchTolerance.setText( str(self.settings.id_length_delta_thresh)) self.leSearchString.setEnabled(False) if self.settings.save_on_low_confidence: self.cbxSaveOnLowConfidence.setCheckState(QtCore.Qt.Checked) if self.settings.dont_use_year_when_identifying: self.cbxDontUseYear.setCheckState(QtCore.Qt.Checked) if self.settings.assume_1_if_no_issue_num: self.cbxAssumeIssueOne.setCheckState(QtCore.Qt.Checked) if self.settings.ignore_leading_numbers_in_filename: self.cbxIgnoreLeadingDigitsInFilename.setCheckState( QtCore.Qt.Checked) if self.settings.remove_archive_after_successful_match: self.cbxRemoveAfterSuccess.setCheckState(QtCore.Qt.Checked) if self.settings.wait_and_retry_on_rate_limit: self.cbxWaitForRateLimit.setCheckState(QtCore.Qt.Checked) nlmtTip = ( """ <html>The <b>Name Length Match Tolerance</b> is for eliminating automatic search matches that are too long compared to your series name search. The higher it is, the more likely to have a good match, but each search will take longer and use more bandwidth. Too low, and only the very closest lexical matches will be explored.</html>""") self.leNameLengthMatchTolerance.setToolTip(nlmtTip) ssTip = ("""<html> The <b>series search string</b> specifies the search string to be used for all selected archives. Use this when trying to match archives with hard-to-parse or incorrect filenames. All archives selected should be from the same series. </html>""") self.leSearchString.setToolTip(ssTip) self.cbxSpecifySearchString.setToolTip(ssTip) validator = QtGui.QIntValidator(0, 99, self) self.leNameLengthMatchTolerance.setValidator(validator) self.cbxSpecifySearchString.stateChanged.connect( self.searchStringToggle) self.autoSaveOnLow = False self.dontUseYear = False self.assumeIssueOne = False self.ignoreLeadingDigitsInFilename = False self.removeAfterSuccess = False self.waitAndRetryOnRateLimit = False self.searchString = None self.nameLengthMatchTolerance = self.settings.id_length_delta_thresh
def process_file_cli(filename, opts, settings, match_results): batch_mode = len(opts.file_list) > 1 ca = ComicArchive( filename, settings.rar_exe_path, ComicTaggerSettings.getGraphic('nocover.png')) if not os.path.lexists(filename): print >> sys.stderr, "Cannot find " + filename return if not ca.seemsToBeAComicArchive(): print >> sys.stderr, "Sorry, but " + \ filename + " is not a comic archive!" return # if not ca.isWritableForStyle(opts.data_style) and (opts.delete_tags or # opts.save_tags or opts.rename_file): if not ca.isWritable() and ( opts.delete_tags or opts.copy_tags or opts.save_tags or opts.rename_file): print >> sys.stderr, "This archive is not writable for that tag type" return has = [False, False, False] if ca.hasCIX(): has[MetaDataStyle.CIX] = True if ca.hasCBI(): has[MetaDataStyle.CBI] = True if ca.hasCoMet(): has[MetaDataStyle.COMET] = True if opts.print_tags: if opts.data_style is None: page_count = ca.getNumberOfPages() brief = "" if batch_mode: brief = u"{0}: ".format(filename) if ca.isZip(): brief += "ZIP archive " elif ca.isRar(): brief += "RAR archive " elif ca.isFolder(): brief += "Folder archive " brief += "({0: >3} pages)".format(page_count) brief += " tags:[ " if not (has[MetaDataStyle.CBI] or has[ MetaDataStyle.CIX] or has[MetaDataStyle.COMET]): brief += "none " else: if has[MetaDataStyle.CBI]: brief += "CBL " if has[MetaDataStyle.CIX]: brief += "CR " if has[MetaDataStyle.COMET]: brief += "CoMet " brief += "]" print brief if opts.terse: return print if opts.data_style is None or opts.data_style == MetaDataStyle.CIX: if has[MetaDataStyle.CIX]: print("--------- ComicRack tags ---------") if opts.raw: print( u"{0}".format( unicode( ca.readRawCIX(), errors='ignore'))) else: print(u"{0}".format(ca.readCIX())) if opts.data_style is None or opts.data_style == MetaDataStyle.CBI: if has[MetaDataStyle.CBI]: print("------- ComicBookLover tags -------") if opts.raw: pprint(json.loads(ca.readRawCBI())) else: print(u"{0}".format(ca.readCBI())) if opts.data_style is None or opts.data_style == MetaDataStyle.COMET: if has[MetaDataStyle.COMET]: print("----------- CoMet tags -----------") if opts.raw: print(u"{0}".format(ca.readRawCoMet())) else: print(u"{0}".format(ca.readCoMet())) elif opts.delete_tags: style_name = MetaDataStyle.name[opts.data_style] if has[opts.data_style]: if not opts.dryrun: if not ca.removeMetadata(opts.data_style): print(u"{0}: Tag removal seemed to fail!".format(filename)) else: print( u"{0}: Removed {1} tags.".format(filename, style_name)) else: print( u"{0}: dry-run. {1} tags not removed".format(filename, style_name)) else: print(u"{0}: This archive doesn't have {1} tags to remove.".format( filename, style_name)) elif opts.copy_tags: dst_style_name = MetaDataStyle.name[opts.data_style] if opts.no_overwrite and has[opts.data_style]: print(u"{0}: Already has {1} tags. Not overwriting.".format( filename, dst_style_name)) return if opts.copy_source == opts.data_style: print( u"{0}: Destination and source are same: {1}. Nothing to do.".format( filename, dst_style_name)) return src_style_name = MetaDataStyle.name[opts.copy_source] if has[opts.copy_source]: if not opts.dryrun: md = ca.readMetadata(opts.copy_source) if settings.apply_cbl_transform_on_bulk_operation and opts.data_style == MetaDataStyle.CBI: md = CBLTransformer(md, settings).apply() if not ca.writeMetadata(md, opts.data_style): print(u"{0}: Tag copy seemed to fail!".format(filename)) else: print(u"{0}: Copied {1} tags to {2} .".format( filename, src_style_name, dst_style_name)) else: print( u"{0}: dry-run. {1} tags not copied".format(filename, src_style_name)) else: print(u"{0}: This archive doesn't have {1} tags to copy.".format( filename, src_style_name)) elif opts.save_tags: if opts.no_overwrite and has[opts.data_style]: print(u"{0}: Already has {1} tags. Not overwriting.".format( filename, MetaDataStyle.name[opts.data_style])) return if batch_mode: print(u"Processing {0}...".format(filename)) md = create_local_metadata(opts, ca, has[opts.data_style]) if md.issue is None or md.issue == "": if opts.assume_issue_is_one_if_not_set: md.issue = "1" # now, search online if opts.search_online: if opts.issue_id is not None: # we were given the actual ID to search with try: comicVine = ComicVineTalker() comicVine.wait_for_rate_limit = opts.wait_and_retry_on_rate_limit cv_md = comicVine.fetchIssueDataByIssueID( opts.issue_id, settings) except ComicVineTalkerException: print >> sys.stderr, "Network error while getting issue details. Save aborted" match_results.fetchDataFailures.append(filename) return if cv_md is None: print >> sys.stderr, "No match for ID {0} was found.".format( opts.issue_id) match_results.noMatches.append(filename) return if settings.apply_cbl_transform_on_cv_import: cv_md = CBLTransformer(cv_md, settings).apply() else: ii = IssueIdentifier(ca, settings) if md is None or md.isEmpty: print >> sys.stderr, "No metadata given to search online with!" match_results.noMatches.append(filename) return def myoutput(text): if opts.verbose: IssueIdentifier.defaultWriteOutput(text) # use our overlayed MD struct to search ii.setAdditionalMetadata(md) ii.onlyUseAdditionalMetaData = True ii.waitAndRetryOnRateLimit = opts.wait_and_retry_on_rate_limit ii.setOutputFunction(myoutput) ii.cover_page_index = md.getCoverPageIndexList()[0] matches = ii.search() result = ii.search_result found_match = False choices = False low_confidence = False if result == ii.ResultNoMatches: pass elif result == ii.ResultFoundMatchButBadCoverScore: low_confidence = True found_match = True elif result == ii.ResultFoundMatchButNotFirstPage: found_match = True elif result == ii.ResultMultipleMatchesWithBadImageScores: low_confidence = True choices = True elif result == ii.ResultOneGoodMatch: found_match = True elif result == ii.ResultMultipleGoodMatches: choices = True if choices: if low_confidence: print >> sys.stderr, "Online search: Multiple low confidence matches. Save aborted" match_results.lowConfidenceMatches.append( MultipleMatch(filename, matches)) return else: print >> sys.stderr, "Online search: Multiple good matches. Save aborted" match_results.multipleMatches.append( MultipleMatch(filename, matches)) return if low_confidence and opts.abortOnLowConfidence: print >> sys.stderr, "Online search: Low confidence match. Save aborted" match_results.lowConfidenceMatches.append( MultipleMatch(filename, matches)) return if not found_match: print >> sys.stderr, "Online search: No match found. Save aborted" match_results.noMatches.append(filename) return # we got here, so we have a single match # now get the particular issue data cv_md = actual_issue_data_fetch(matches[0], settings, opts) if cv_md is None: match_results.fetchDataFailures.append(filename) return md.overlay(cv_md) # ok, done building our metadata. time to save if not actual_metadata_save(ca, opts, md): match_results.writeFailures.append(filename) else: match_results.goodMatches.append(filename) elif opts.rename_file: msg_hdr = "" if batch_mode: msg_hdr = u"{0}: ".format(filename) if opts.data_style is not None: use_tags = has[opts.data_style] else: use_tags = False md = create_local_metadata(opts, ca, use_tags) if md.series is None: print >> sys.stderr, msg_hdr + "Can't rename without series name" return new_ext = None # default if settings.rename_extension_based_on_archive: if ca.isZip(): new_ext = ".cbz" elif ca.isRar(): new_ext = ".cbr" renamer = FileRenamer(md) renamer.setTemplate(settings.rename_template) renamer.setIssueZeroPadding(settings.rename_issue_number_padding) renamer.setSmartCleanup(settings.rename_use_smart_string_cleanup) new_name = renamer.determineName(filename, ext=new_ext) if new_name == os.path.basename(filename): print >> sys.stderr, msg_hdr + "Filename is already good!" return folder = os.path.dirname(os.path.abspath(filename)) new_abs_path = utils.unique_file(os.path.join(folder, new_name)) suffix = "" if not opts.dryrun: # rename the file os.rename(filename, new_abs_path) else: suffix = " (dry-run, no change)" print( u"renamed '{0}' -> '{1}' {2}".format(os.path.basename(filename), new_name, suffix)) elif opts.export_to_zip: msg_hdr = "" if batch_mode: msg_hdr = u"{0}: ".format(filename) if not ca.isRar(): print >> sys.stderr, msg_hdr + "Archive is not a RAR." return rar_file = os.path.abspath(os.path.abspath(filename)) new_file = os.path.splitext(rar_file)[0] + ".cbz" if opts.abort_export_on_conflict and os.path.lexists(new_file): print msg_hdr + "{0} already exists in the that folder.".format(os.path.split(new_file)[1]) return new_file = utils.unique_file(os.path.join(new_file)) delete_success = False export_success = False if not opts.dryrun: if ca.exportAsZip(new_file): export_success = True if opts.delete_rar_after_export: try: os.unlink(rar_file) except: print >> sys.stderr, msg_hdr + \ "Error deleting original RAR after export" delete_success = False else: delete_success = True else: # last export failed, so remove the zip, if it exists if os.path.lexists(new_file): os.remove(new_file) else: msg = msg_hdr + \ u"Dry-run: Would try to create {0}".format( os.path.split(new_file)[1]) if opts.delete_rar_after_export: msg += u" and delete orginal." print(msg) return msg = msg_hdr if export_success: msg += u"Archive exported successfully to: {0}".format( os.path.split(new_file)[1]) if opts.delete_rar_after_export and delete_success: msg += u" (Original deleted) " else: msg += u"Archive failed to export!" print(msg)