def __init__(self, files, parent=None): QtGui.QDialog.__init__(self, parent) self.ui = Ui_TagsFromFileNamesDialog() self.ui.setupUi(self) items = [ "%artist%/%album%/%tracknumber% %title%", "%artist%/%album%/%tracknumber% - %title%", "%artist%/%album - %tracknumber% - %title%", ] format = config.persist["tags_from_filenames_format"] if format and format not in items: items.insert(0, format) self.ui.format.addItems(items) self.ui.buttonbox.addButton(StandardButton(StandardButton.OK), QtGui.QDialogButtonBox.AcceptRole) self.ui.buttonbox.addButton(StandardButton(StandardButton.CANCEL), QtGui.QDialogButtonBox.RejectRole) self.ui.buttonbox.accepted.connect(self.accept) self.ui.buttonbox.rejected.connect(self.reject) self.ui.preview.clicked.connect(self.preview) self.ui.files.setHeaderLabels([_("File Name")]) self.restoreWindowState() self.files = files self.items = [] for file in files: item = QtGui.QTreeWidgetItem(self.ui.files) item.setText(0, os.path.basename(file.filename)) self.items.append(item) self._tag_re = re.compile("(%\w+%)")
def __init__(self, files, parent=None): PicardDialog.__init__(self, parent) self.ui = Ui_TagsFromFileNamesDialog() self.ui.setupUi(self) items = [ "%artist%/%album%/%tracknumber% %title%", "%artist%/%album%/%tracknumber% - %title%", "%artist%/%album - %tracknumber% - %title%", ] format = config.persist["tags_from_filenames_format"] if format and format not in items: items.insert(0, format) self.ui.format.addItems(items) self.ui.buttonbox.addButton(StandardButton(StandardButton.OK), QtGui.QDialogButtonBox.AcceptRole) self.ui.buttonbox.addButton(StandardButton(StandardButton.CANCEL), QtGui.QDialogButtonBox.RejectRole) self.ui.buttonbox.accepted.connect(self.accept) self.ui.buttonbox.rejected.connect(self.reject) self.ui.preview.clicked.connect(self.preview) self.ui.files.setHeaderLabels([_("File Name")]) self.restoreWindowState() self.files = files self.items = [] for file in files: item = QtGui.QTreeWidgetItem(self.ui.files) item.setText(0, os.path.basename(file.filename)) self.items.append(item) self._tag_re = re.compile("(%\w+%)")
def __init__(self, files, parent=None): super().__init__(parent) self.ui = Ui_TagsFromFileNamesDialog() self.ui.setupUi(self) items = [ "%artist%/%album%/%title%", "%artist%/%album%/%tracknumber% %title%", "%artist%/%album%/%tracknumber% - %title%", "%artist%/%album% - %tracknumber% - %title%", "%artist% - %album%/%title%", "%artist% - %album%/%tracknumber% %title%", "%artist% - %album%/%tracknumber% - %title%", ] config = get_config() tff_format = config.persist["tags_from_filenames_format"] if tff_format not in items: selected_index = 0 if tff_format: items.insert(0, tff_format) else: selected_index = items.index(tff_format) self.ui.format.addItems(items) self.ui.format.setCurrentIndex(selected_index) self.ui.buttonbox.addButton( StandardButton(StandardButton.HELP), QtWidgets.QDialogButtonBox.ButtonRole.HelpRole) self.ui.buttonbox.addButton( StandardButton(StandardButton.OK), QtWidgets.QDialogButtonBox.ButtonRole.AcceptRole) self.ui.buttonbox.addButton( StandardButton(StandardButton.CANCEL), QtWidgets.QDialogButtonBox.ButtonRole.RejectRole) self.ui.buttonbox.accepted.connect(self.accept) self.ui.buttonbox.rejected.connect(self.reject) self.ui.buttonbox.helpRequested.connect(self.show_help) self.ui.preview.clicked.connect(self.preview) self.ui.files.setHeaderLabels([_("File Name")]) self.files = files self.items = [] for file in files: item = QtWidgets.QTreeWidgetItem(self.ui.files) item.setText(0, os.path.basename(file.filename)) self.items.append(item)
def __init__(self, files, parent=None): PicardDialog.__init__(self, parent) self.ui = Ui_TagsFromFileNamesDialog() self.ui.setupUi(self) items = [ "%artist%/%album%/%title%", "%artist%/%album%/%tracknumber% %title%", "%artist%/%album%/%tracknumber% - %title%", "%artist%/%album% - %tracknumber% - %title%", "%artist% - %album%/%title%", "%artist% - %album%/%tracknumber% %title%", "%artist% - %album%/%tracknumber% - %title%", ] tff_format = config.persist["tags_from_filenames_format"] if tff_format not in items: selected_index = 0 if tff_format: items.insert(0, tff_format) else: selected_index = items.index(tff_format) self.ui.format.addItems(items) self.ui.format.setCurrentIndex(selected_index) self.ui.buttonbox.addButton(StandardButton(StandardButton.OK), QtWidgets.QDialogButtonBox.AcceptRole) self.ui.buttonbox.addButton(StandardButton(StandardButton.CANCEL), QtWidgets.QDialogButtonBox.RejectRole) self.ui.buttonbox.accepted.connect(self.accept) self.ui.buttonbox.rejected.connect(self.reject) self.ui.preview.clicked.connect(self.preview) self.ui.files.setHeaderLabels([_("File Name")]) self.restoreWindowState() self.files = files self.items = [] for file in files: item = QtWidgets.QTreeWidgetItem(self.ui.files) item.setText(0, os.path.basename(file.filename)) self.items.append(item) self._tag_re = re.compile(r"(%\w+%)") self.numeric_tags = ('tracknumber', 'totaltracks', 'discnumber', 'totaldiscs')
def __init__(self, files, parent=None): super().__init__(parent) self.ui = Ui_TagsFromFileNamesDialog() self.ui.setupUi(self) items = [ "%artist%/%album%/%title%", "%artist%/%album%/%tracknumber% %title%", "%artist%/%album%/%tracknumber% - %title%", "%artist%/%album% - %tracknumber% - %title%", "%artist% - %album%/%title%", "%artist% - %album%/%tracknumber% %title%", "%artist% - %album%/%tracknumber% - %title%", ] tff_format = config.persist["tags_from_filenames_format"] if tff_format not in items: selected_index = 0 if tff_format: items.insert(0, tff_format) else: selected_index = items.index(tff_format) self.ui.format.addItems(items) self.ui.format.setCurrentIndex(selected_index) self.ui.buttonbox.addButton(StandardButton(StandardButton.OK), QtWidgets.QDialogButtonBox.AcceptRole) self.ui.buttonbox.addButton(StandardButton(StandardButton.CANCEL), QtWidgets.QDialogButtonBox.RejectRole) self.ui.buttonbox.accepted.connect(self.accept) self.ui.buttonbox.rejected.connect(self.reject) self.ui.preview.clicked.connect(self.preview) self.ui.files.setHeaderLabels([_("File Name")]) self.files = files self.items = [] for file in files: item = QtWidgets.QTreeWidgetItem(self.ui.files) item.setText(0, os.path.basename(file.filename)) self.items.append(item) self._tag_re = re.compile(r"(%\w+%)") self.numeric_tags = ('tracknumber', 'totaltracks', 'discnumber', 'totaldiscs')
class TagsFromFileNamesDialog(PicardDialog): options = [ config.TextOption("persist", "tags_from_filenames_format", ""), config.Option("persist", "tags_from_filenames_position", QtCore.QPoint()), config.Option("persist", "tags_from_filenames_size", QtCore.QSize(560, 400)), ] def __init__(self, files, parent=None): PicardDialog.__init__(self, parent) self.ui = Ui_TagsFromFileNamesDialog() self.ui.setupUi(self) items = [ "%artist%/%album%/%tracknumber% %title%", "%artist%/%album%/%tracknumber% - %title%", "%artist%/%album - %tracknumber% - %title%", ] format = config.persist["tags_from_filenames_format"] if format and format not in items: items.insert(0, format) self.ui.format.addItems(items) self.ui.buttonbox.addButton(StandardButton(StandardButton.OK), QtGui.QDialogButtonBox.AcceptRole) self.ui.buttonbox.addButton(StandardButton(StandardButton.CANCEL), QtGui.QDialogButtonBox.RejectRole) self.ui.buttonbox.accepted.connect(self.accept) self.ui.buttonbox.rejected.connect(self.reject) self.ui.preview.clicked.connect(self.preview) self.ui.files.setHeaderLabels([_("File Name")]) self.restoreWindowState() self.files = files self.items = [] for file in files: item = QtGui.QTreeWidgetItem(self.ui.files) item.setText(0, os.path.basename(file.filename)) self.items.append(item) self._tag_re = re.compile("(%\w+%)") def parse_format(self): format = unicode(self.ui.format.currentText()) columns = [] format_re = ["(?:^|/)"] for part in self._tag_re.split(format): if part.startswith("%") and part.endswith("%"): name = part[1:-1] columns.append(name) if name in ("tracknumber", "totaltracks", "discnumber", "totaldiscs"): format_re.append("(?P<" + name + ">\d+)") elif name in ("date"): format_re.append("(?P<" + name + ">\d+(?:-\d+(?:-\d+)?)?)") else: format_re.append("(?P<" + name + ">[^/]*?)") else: format_re.append(re.escape(part)) format_re.append("\\.(\\w+)$") format_re = re.compile("".join(format_re)) return format_re, columns def match_file(self, file, format): match = format.search("/".join(os.path.split(file.filename))) if match: result = {} for name, value in match.groupdict().iteritems(): value = value.strip() if self.ui.replace_underscores.isChecked(): value = value.replace("_", " ") result[name] = value return result else: return {} def preview(self): format, columns = self.parse_format() self.ui.files.setHeaderLabels([_("File Name")] + map(display_tag_name, columns)) for item, file in zip(self.items, self.files): matches = self.match_file(file, format) for i in range(len(columns)): value = matches.get(columns[i], "") item.setText(i + 1, value) self.ui.files.header().resizeSections(QtGui.QHeaderView.ResizeToContents) self.ui.files.header().setStretchLastSection(True) def accept(self): format, columns = self.parse_format() for file in self.files: metadata = self.match_file(file, format) for name, value in metadata.iteritems(): file.metadata[name] = value file.update() config.persist["tags_from_filenames_format"] = self.ui.format.currentText() self.saveWindowState() QtGui.QDialog.accept(self) def reject(self): self.saveWindowState() QtGui.QDialog.reject(self) def closeEvent(self, event): self.saveWindowState() event.accept() def saveWindowState(self): pos = self.pos() if not pos.isNull(): config.persist["tags_from_filenames_position"] = pos config.persist["tags_from_filenames_size"] = self.size() def restoreWindowState(self): pos = config.persist["tags_from_filenames_position"] if pos.x() > 0 and pos.y() > 0: self.move(pos) self.resize(config.persist["tags_from_filenames_size"])
class TagsFromFileNamesDialog(PicardDialog): help_url = 'doc_tags_from_filenames' options = [ TextOption("persist", "tags_from_filenames_format", ""), ] def __init__(self, files, parent=None): super().__init__(parent) self.ui = Ui_TagsFromFileNamesDialog() self.ui.setupUi(self) items = [ "%artist%/%album%/%title%", "%artist%/%album%/%tracknumber% %title%", "%artist%/%album%/%tracknumber% - %title%", "%artist%/%album% - %tracknumber% - %title%", "%artist% - %album%/%title%", "%artist% - %album%/%tracknumber% %title%", "%artist% - %album%/%tracknumber% - %title%", ] config = get_config() tff_format = config.persist["tags_from_filenames_format"] if tff_format not in items: selected_index = 0 if tff_format: items.insert(0, tff_format) else: selected_index = items.index(tff_format) self.ui.format.addItems(items) self.ui.format.setCurrentIndex(selected_index) self.ui.buttonbox.addButton( StandardButton(StandardButton.HELP), QtWidgets.QDialogButtonBox.ButtonRole.HelpRole) self.ui.buttonbox.addButton( StandardButton(StandardButton.OK), QtWidgets.QDialogButtonBox.ButtonRole.AcceptRole) self.ui.buttonbox.addButton( StandardButton(StandardButton.CANCEL), QtWidgets.QDialogButtonBox.ButtonRole.RejectRole) self.ui.buttonbox.accepted.connect(self.accept) self.ui.buttonbox.rejected.connect(self.reject) self.ui.buttonbox.helpRequested.connect(self.show_help) self.ui.preview.clicked.connect(self.preview) self.ui.files.setHeaderLabels([_("File Name")]) self.files = files self.items = [] for file in files: item = QtWidgets.QTreeWidgetItem(self.ui.files) item.setText(0, os.path.basename(file.filename)) self.items.append(item) def preview(self): expression = TagMatchExpression( self.ui.format.currentText(), self.ui.replace_underscores.isChecked()) columns = expression.matched_tags headers = [_("File Name")] + list(map(display_tag_name, columns)) self.ui.files.setColumnCount(len(headers)) self.ui.files.setHeaderLabels(headers) for item, file in zip(self.items, self.files): matches = expression.match_file(file.filename) for i, column in enumerate(columns): values = matches.get(column, []) item.setText(i + 1, '; '.join(values)) self.ui.files.header().resizeSections( QtWidgets.QHeaderView.ResizeMode.ResizeToContents) self.ui.files.header().setStretchLastSection(True) def accept(self): expression = TagMatchExpression( self.ui.format.currentText(), self.ui.replace_underscores.isChecked()) for file in self.files: metadata = expression.match_file(file.filename) file.metadata.update(metadata) file.update() config = get_config() config.persist[ "tags_from_filenames_format"] = self.ui.format.currentText() super().accept()
class TagsFromFileNamesDialog(QtGui.QDialog): options = [ config.TextOption("persist", "tags_from_filenames_format", ""), config.Option("persist", "tags_from_filenames_position", QtCore.QPoint(), QtCore.QVariant.toPoint), config.Option("persist", "tags_from_filenames_size", QtCore.QSize(560, 400), QtCore.QVariant.toSize), ] def __init__(self, files, parent=None): QtGui.QDialog.__init__(self, parent) self.ui = Ui_TagsFromFileNamesDialog() self.ui.setupUi(self) items = [ "%artist%/%album%/%tracknumber% %title%", "%artist%/%album%/%tracknumber% - %title%", "%artist%/%album - %tracknumber% - %title%", ] format = config.persist["tags_from_filenames_format"] if format and format not in items: items.insert(0, format) self.ui.format.addItems(items) self.ui.buttonbox.addButton(StandardButton(StandardButton.OK), QtGui.QDialogButtonBox.AcceptRole) self.ui.buttonbox.addButton(StandardButton(StandardButton.CANCEL), QtGui.QDialogButtonBox.RejectRole) self.ui.buttonbox.accepted.connect(self.accept) self.ui.buttonbox.rejected.connect(self.reject) self.ui.preview.clicked.connect(self.preview) self.ui.files.setHeaderLabels([_("File Name")]) self.restoreWindowState() self.files = files self.items = [] for file in files: item = QtGui.QTreeWidgetItem(self.ui.files) item.setText(0, os.path.basename(file.filename)) self.items.append(item) self._tag_re = re.compile("(%\w+%)") def parse_format(self): format = unicode(self.ui.format.currentText()) columns = [] format_re = ['(?:^|/)'] for part in self._tag_re.split(format): if part.startswith('%') and part.endswith('%'): name = part[1:-1] columns.append(name) if name in ('tracknumber', 'totaltracks', 'discnumber', 'totaldiscs'): format_re.append('(?P<' + name + '>\d+)') elif name in ('date'): format_re.append('(?P<' + name + '>\d+(?:-\d+(?:-\d+)?)?)') else: format_re.append('(?P<' + name + '>[^/]*?)') else: format_re.append(re.escape(part)) format_re.append('\\.(\\w+)$') format_re = re.compile("".join(format_re)) return format_re, columns def match_file(self, file, format): match = format.search('/'.join(os.path.split(file.filename))) if match: result = {} for name, value in match.groupdict().iteritems(): value = value.strip() if self.ui.replace_underscores.isChecked(): value = value.replace('_', ' ') result[name] = value return result else: return {} def preview(self): format, columns = self.parse_format() self.ui.files.setHeaderLabels([_("File Name")] + map(display_tag_name, columns)) for item, file in zip(self.items, self.files): matches = self.match_file(file, format) for i in range(len(columns)): value = matches.get(columns[i], '') item.setText(i + 1, value) self.ui.files.header().resizeSections(QtGui.QHeaderView.ResizeToContents) self.ui.files.header().setStretchLastSection(True) def accept(self): format, columns = self.parse_format() for file in self.files: metadata = self.match_file(file, format) for name, value in metadata.iteritems(): file.metadata[name] = value file.update() config.persist["tags_from_filenames_format"] = self.ui.format.currentText() self.saveWindowState() QtGui.QDialog.accept(self) def reject(self): self.saveWindowState() QtGui.QDialog.reject(self) def closeEvent(self, event): self.saveWindowState() event.accept() def saveWindowState(self): pos = self.pos() if not pos.isNull(): config.persist["tags_from_filenames_position"] = pos config.persist["tags_from_filenames_size"] = self.size() def restoreWindowState(self): pos = config.persist["tags_from_filenames_position"] if pos.x() > 0 and pos.y() > 0: self.move(pos) self.resize(config.persist["tags_from_filenames_size"])
class TagsFromFileNamesDialog(PicardDialog): options = [ config.TextOption("persist", "tags_from_filenames_format", ""), ] def __init__(self, files, parent=None): super().__init__(parent) self.ui = Ui_TagsFromFileNamesDialog() self.ui.setupUi(self) items = [ "%artist%/%album%/%title%", "%artist%/%album%/%tracknumber% %title%", "%artist%/%album%/%tracknumber% - %title%", "%artist%/%album% - %tracknumber% - %title%", "%artist% - %album%/%title%", "%artist% - %album%/%tracknumber% %title%", "%artist% - %album%/%tracknumber% - %title%", ] tff_format = config.persist["tags_from_filenames_format"] if tff_format not in items: selected_index = 0 if tff_format: items.insert(0, tff_format) else: selected_index = items.index(tff_format) self.ui.format.addItems(items) self.ui.format.setCurrentIndex(selected_index) self.ui.buttonbox.addButton(StandardButton(StandardButton.OK), QtWidgets.QDialogButtonBox.AcceptRole) self.ui.buttonbox.addButton(StandardButton(StandardButton.CANCEL), QtWidgets.QDialogButtonBox.RejectRole) self.ui.buttonbox.accepted.connect(self.accept) self.ui.buttonbox.rejected.connect(self.reject) self.ui.preview.clicked.connect(self.preview) self.ui.files.setHeaderLabels([_("File Name")]) self.files = files self.items = [] for file in files: item = QtWidgets.QTreeWidgetItem(self.ui.files) item.setText(0, os.path.basename(file.filename)) self.items.append(item) self._tag_re = re.compile(r"(%\w+%)") self.numeric_tags = ('tracknumber', 'totaltracks', 'discnumber', 'totaldiscs') def parse_response(self): tff_format = self.ui.format.currentText() columns = [] format_re = ['(?:^|/)'] for part in self._tag_re.split(tff_format): if part.startswith('%') and part.endswith('%'): name = part[1:-1] columns.append(name) if name in self.numeric_tags: format_re.append('(?P<' + name + r'>\d+)') elif name == 'date': format_re.append('(?P<' + name + r'>\d+(?:-\d+(?:-\d+)?)?)') else: format_re.append('(?P<' + name + '>[^/]*?)') else: format_re.append(re.escape(part)) format_re.append(r'\.(\w+)$') format_re = re.compile("".join(format_re)) return format_re, columns def match_file(self, file, tff_format): match = tff_format.search(file.filename.replace('\\', '/')) if match: result = {} for name, value in match.groupdict().items(): value = value.strip() if name in self.numeric_tags: value = value.lstrip("0") if self.ui.replace_underscores.isChecked(): value = value.replace('_', ' ') result[name] = value return result else: return {} def preview(self): tff_format, columns = self.parse_response() self.ui.files.setHeaderLabels([_("File Name")] + list(map(display_tag_name, columns))) for item, file in zip(self.items, self.files): matches = self.match_file(file, tff_format) for i, column in enumerate(columns): item.setText(i + 1, matches.get(column, '')) self.ui.files.header().resizeSections( QtWidgets.QHeaderView.ResizeToContents) self.ui.files.header().setStretchLastSection(True) def accept(self): tff_format, columns = self.parse_response() for file in self.files: metadata = self.match_file(file, tff_format) for name, value in metadata.items(): file.metadata[name] = value file.update() config.persist[ "tags_from_filenames_format"] = self.ui.format.currentText() super().accept()
class TagsFromFileNamesDialog(PicardDialog): options = [ config.TextOption("persist", "tags_from_filenames_format", ""), config.Option("persist", "tags_from_filenames_position", QtCore.QPoint()), config.Option("persist", "tags_from_filenames_size", QtCore.QSize(560, 400)), ] def __init__(self, files, parent=None): PicardDialog.__init__(self, parent) self.ui = Ui_TagsFromFileNamesDialog() self.ui.setupUi(self) items = [ "%artist%/%album%/%title%", "%artist%/%album%/%tracknumber% %title%", "%artist%/%album%/%tracknumber% - %title%", "%artist%/%album% - %tracknumber% - %title%", "%artist% - %album%/%title%", "%artist% - %album%/%tracknumber% %title%", "%artist% - %album%/%tracknumber% - %title%", ] tff_format = config.persist["tags_from_filenames_format"] if tff_format not in items: selected_index = 0 if tff_format: items.insert(0, tff_format) else: selected_index = items.index(tff_format) self.ui.format.addItems(items) self.ui.format.setCurrentIndex(selected_index) self.ui.buttonbox.addButton(StandardButton(StandardButton.OK), QtWidgets.QDialogButtonBox.AcceptRole) self.ui.buttonbox.addButton(StandardButton(StandardButton.CANCEL), QtWidgets.QDialogButtonBox.RejectRole) self.ui.buttonbox.accepted.connect(self.accept) self.ui.buttonbox.rejected.connect(self.reject) self.ui.preview.clicked.connect(self.preview) self.ui.files.setHeaderLabels([_("File Name")]) self.restoreWindowState() self.files = files self.items = [] for file in files: item = QtWidgets.QTreeWidgetItem(self.ui.files) item.setText(0, os.path.basename(file.filename)) self.items.append(item) self._tag_re = re.compile(r"(%\w+%)") self.numeric_tags = ('tracknumber', 'totaltracks', 'discnumber', 'totaldiscs') def parse_format(self): tff_format = self.ui.format.currentText() columns = [] format_re = ['(?:^|/)'] for part in self._tag_re.split(tff_format): if part.startswith('%') and part.endswith('%'): name = part[1:-1] columns.append(name) if name in self.numeric_tags: format_re.append('(?P<' + name + r'>\d+)') elif name in ('date'): format_re.append('(?P<' + name + r'>\d+(?:-\d+(?:-\d+)?)?)') else: format_re.append('(?P<' + name + '>[^/]*?)') else: format_re.append(re.escape(part)) format_re.append(r'\.(\w+)$') format_re = re.compile("".join(format_re)) return format_re, columns def match_file(self, file, tff_format): match = tff_format.search(file.filename.replace('\\','/')) if match: result = {} for name, value in match.groupdict().items(): value = value.strip() if name in self.numeric_tags: value = value.lstrip("0") if self.ui.replace_underscores.isChecked(): value = value.replace('_', ' ') result[name] = value return result else: return {} def preview(self): tff_format, columns = self.parse_format() self.ui.files.setHeaderLabels([_("File Name")] + list(map(display_tag_name, columns))) for item, file in zip(self.items, self.files): matches = self.match_file(file, tff_format) for i, column in enumerate(columns): item.setText(i + 1, matches.get(column, '')) self.ui.files.header().resizeSections(QtWidgets.QHeaderView.ResizeToContents) self.ui.files.header().setStretchLastSection(True) def accept(self): tff_format, columns = self.parse_format() for file in self.files: metadata = self.match_file(file, tff_format) for name, value in metadata.items(): file.metadata[name] = value file.update() config.persist["tags_from_filenames_format"] = self.ui.format.currentText() self.saveWindowState() QtWidgets.QDialog.accept(self) def reject(self): self.saveWindowState() QtWidgets.QDialog.reject(self) def closeEvent(self, event): self.saveWindowState() event.accept() def saveWindowState(self): pos = self.pos() if not pos.isNull(): config.persist["tags_from_filenames_position"] = pos config.persist["tags_from_filenames_size"] = self.size() def restoreWindowState(self): pos = config.persist["tags_from_filenames_position"] if pos.x() > 0 and pos.y() > 0: self.move(pos) self.resize(config.persist["tags_from_filenames_size"])