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()
Esempio n. 2
0
	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()		
Esempio n. 3
0
    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()
Esempio n. 4
0
	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 )
Esempio n. 5
0
    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()
Esempio n. 6
0
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())
Esempio n. 7
0
File: main.py Progetto: xeddmc/mylar
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())
Esempio n. 8
0
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)
Esempio n. 9
0
	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)
Esempio n. 10
0
	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)
Esempio n. 11
0
    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)
Esempio n. 12
0
	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()		
Esempio n. 13
0
	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)
Esempio n. 15
0
    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()
Esempio n. 16
0
    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)
Esempio n. 18
0
    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()
Esempio n. 19
0
    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)
Esempio n. 20
0
	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()
Esempio n. 21
0
    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)
Esempio n. 22
0
	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)
Esempio n. 23
0
    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)
Esempio n. 24
0
    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)
Esempio n. 25
0
    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()
Esempio n. 26
0
	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()
Esempio n. 27
0
    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
Esempio n. 29
0
    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
Esempio n. 30
0
	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
Esempio n. 31
0
    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)
Esempio n. 32
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
Esempio n. 34
0
    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
Esempio n. 35
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()
Esempio n. 36
0
    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
Esempio n. 37
0
    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
Esempio n. 38
0
	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
Esempio n. 39
0
	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()
Esempio n. 40
0
 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
Esempio n. 41
0
File: utils.py Progetto: 2mny/mylar
	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
Esempio n. 42
0
    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()
Esempio n. 43
0
    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()
Esempio n. 44
0
    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()
Esempio n. 45
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()
Esempio n. 46
0
    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)
Esempio n. 47
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()
Esempio n. 48
0
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)
Esempio n. 49
0
	def loadDefault( self ):
		self.current_pixmap = QPixmap(ComicTaggerSettings.getGraphic('nocover.png'))
		#print "loadDefault called"
		self.setDisplayPixmap( 0, 0)
Esempio n. 50
0
 def loadDefault(self):
     self.current_pixmap = QPixmap(
         ComicTaggerSettings.getGraphic('nocover.png'))
     #print("loadDefault called")
     self.setDisplayPixmap(0, 0)
Esempio n. 51
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)
Esempio n. 52
0
        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
Esempio n. 53
0
    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
Esempio n. 54
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)