Merge branch 'removeRenamer' into develop

This commit is contained in:
Timmy Welch 2022-04-29 23:29:24 -07:00
commit 049971a78a
9 changed files with 29 additions and 253 deletions

View File

@ -27,7 +27,7 @@ from comicapi.comicarchive import ComicArchive, MetaDataStyle
from comicapi.genericmetadata import GenericMetadata
from comictaggerlib.cbltransformer import CBLTransformer
from comictaggerlib.comicvinetalker import ComicVineTalker, ComicVineTalkerException
from comictaggerlib.filerenamer import FileRenamer, FileRenamer2
from comictaggerlib.filerenamer import FileRenamer
from comictaggerlib.issueidentifier import IssueIdentifier
from comictaggerlib.resulttypes import MultipleMatch, OnlineMatchResults
from comictaggerlib.settings import ComicTaggerSettings
@ -155,13 +155,6 @@ def cli_mode(opts, settings):
logger.error("You must specify at least one filename. Use the -h option for more info")
return
if not settings.hide_rename_message:
print(
"There is a new rename template format available. "
"Please use the settings window to enable and test if you use this feature.\n\n"
"The old rename template format will be removed in the next release, "
"please reference the template help button in the settings or https://github.com/comictagger/comictagger/wiki/UserGuide#rename",
)
match_results = OnlineMatchResults()
for f in opts.file_list:
@ -452,10 +445,7 @@ def process_file_cli(filename, opts, settings, match_results: OnlineMatchResults
elif ca.is_rar():
new_ext = ".cbr"
if settings.rename_new_renamer:
renamer = FileRenamer2(md, platform="universal" if settings.rename_strict else "auto")
else:
renamer = FileRenamer(md)
renamer = FileRenamer(md, platform="universal" if settings.rename_strict else "auto")
renamer.set_template(settings.rename_template)
renamer.set_issue_zero_padding(settings.rename_issue_number_padding)
renamer.set_smart_cleanup(settings.rename_use_smart_string_cleanup)

View File

@ -15,10 +15,9 @@
# limitations under the License.
import calendar
import datetime
import logging
import os
import re
import pathlib
import string
import sys
@ -30,121 +29,6 @@ from comicapi.issuestring import IssueString
logger = logging.getLogger(__name__)
class FileRenamer:
def __init__(self, metadata):
self.template = "%series% v%volume% #%issue% (of %issuecount%) (%year%)"
self.smart_cleanup = True
self.issue_zero_padding = 3
self.metadata = metadata
def set_metadata(self, metadata: GenericMetadata):
self.metadata = metadata
def set_issue_zero_padding(self, count):
self.issue_zero_padding = count
def set_smart_cleanup(self, on):
self.smart_cleanup = on
def set_template(self, template: str):
self.template = template
def replace_token(self, text, value, token):
# helper func
def is_token(word):
return word[0] == "%" and word[-1:] == "%"
if value is not None:
return text.replace(token, str(value))
if self.smart_cleanup:
# smart cleanup means we want to remove anything appended to token if it's empty (e.g "#%issue%" or "v%volume%")
# (TODO: This could fail if there is more than one token appended together, I guess)
text_list = text.split()
# special case for issuecount, remove preceding non-token word, as in "...(of %issuecount%)..."
if token == "%issuecount%":
for idx, word in enumerate(text_list):
if token in word and not is_token(text_list[idx - 1]):
text_list[idx - 1] = ""
text_list = [x for x in text_list if token not in x]
return " ".join(text_list)
return text.replace(token, "")
def determine_name(self, ext):
md = self.metadata
new_name = self.template
new_name = self.replace_token(new_name, md.series, "%series%")
new_name = self.replace_token(new_name, md.volume, "%volume%")
if md.issue is not None:
issue_str = IssueString(md.issue).as_string(pad=self.issue_zero_padding)
else:
issue_str = None
new_name = self.replace_token(new_name, issue_str, "%issue%")
new_name = self.replace_token(new_name, md.issue_count, "%issuecount%")
new_name = self.replace_token(new_name, md.year, "%year%")
new_name = self.replace_token(new_name, md.publisher, "%publisher%")
new_name = self.replace_token(new_name, md.title, "%title%")
new_name = self.replace_token(new_name, md.month, "%month%")
month_name = None
if md.month is not None:
if (isinstance(md.month, str) and md.month.isdigit()) or isinstance(md.month, int):
if int(md.month) in range(1, 13):
dt = datetime.datetime(1970, int(md.month), 1, 0, 0)
month_name = dt.strftime("%B")
new_name = self.replace_token(new_name, month_name, "%month_name%")
new_name = self.replace_token(new_name, md.genre, "%genre%")
new_name = self.replace_token(new_name, md.language, "%language_code%")
new_name = self.replace_token(new_name, md.critical_rating, "%criticalrating%")
new_name = self.replace_token(new_name, md.alternate_series, "%alternateseries%")
new_name = self.replace_token(new_name, md.alternate_number, "%alternatenumber%")
new_name = self.replace_token(new_name, md.alternate_count, "%alternatecount%")
new_name = self.replace_token(new_name, md.imprint, "%imprint%")
new_name = self.replace_token(new_name, md.format, "%format%")
new_name = self.replace_token(new_name, md.maturity_rating, "%maturityrating%")
new_name = self.replace_token(new_name, md.story_arc, "%storyarc%")
new_name = self.replace_token(new_name, md.series_group, "%seriesgroup%")
new_name = self.replace_token(new_name, md.scan_info, "%scaninfo%")
if self.smart_cleanup:
# remove empty braces,brackets, parentheses
new_name = re.sub(r"\(\s*[-:]*\s*\)", "", new_name)
new_name = re.sub(r"\[\s*[-:]*\s*]", "", new_name)
new_name = re.sub(r"{\s*[-:]*\s*}", "", new_name)
# remove duplicate spaces
new_name = " ".join(new_name.split())
# remove remove duplicate -, _,
new_name = re.sub(r"[-_]{2,}\s+", "-- ", new_name)
new_name = re.sub(r"(\s--)+", " --", new_name)
new_name = re.sub(r"(\s-)+", " -", new_name)
# remove dash or double dash at end of line
new_name = re.sub(r"[-]{1,2}\s*$", "", new_name)
# remove duplicate spaces (again!)
new_name = " ".join(new_name.split())
new_name += ext
# some tweaks to keep various filesystems happy
new_name = new_name.replace("/", "-")
new_name = new_name.replace(" :", " -")
new_name = new_name.replace(": ", " - ")
new_name = new_name.replace(":", "-")
new_name = new_name.replace("?", "")
return new_name
class MetadataFormatter(string.Formatter):
def __init__(self, smart_cleanup=False, platform="auto"):
super().__init__()
@ -224,7 +108,7 @@ class MetadataFormatter(string.Formatter):
return "".join(result), auto_arg_index
class FileRenamer2:
class FileRenamer:
def __init__(self, metadata, platform="auto"):
self.template = "{publisher}/{series}/{series} v{volume} #{issue} (of {issue_count}) ({year})"
self.smart_cleanup = True
@ -257,7 +141,6 @@ class FileRenamer2:
template = self.template
path_components = template.split(os.sep)
new_name = ""
fmt = MetadataFormatter(self.smart_cleanup, platform=self.platform)
@ -272,7 +155,7 @@ class FileRenamer2:
md_dict["month_name"] = ""
md_dict["month_abbr"] = ""
for Component in path_components:
for Component in pathlib.PureWindowsPath(template).parts:
if (
self.platform.lower() in ["universal", "windows"] or sys.platform.lower() in ["windows"]
) and self.smart_cleanup:

View File

@ -23,7 +23,7 @@ from PyQt5 import QtCore, QtWidgets, uic
import comicapi.comicarchive
from comicapi import utils
from comicapi.comicarchive import MetaDataStyle
from comictaggerlib.filerenamer import FileRenamer, FileRenamer2
from comictaggerlib.filerenamer import FileRenamer
from comictaggerlib.settings import ComicTaggerSettings
from comictaggerlib.settingswindow import SettingsWindow
from comictaggerlib.ui.qtutils import center_window_on_parent
@ -52,10 +52,7 @@ class RenameWindow(QtWidgets.QDialog):
self.rename_list = []
self.btnSettings.clicked.connect(self.modify_settings)
if self.settings.rename_new_renamer:
self.renamer = FileRenamer2(None, platform="universal" if self.settings.rename_strict else "auto")
else:
self.renamer = FileRenamer(None)
self.renamer = FileRenamer(None, platform="universal" if self.settings.rename_strict else "auto")
self.config_renamer()
self.do_preview()

View File

@ -86,7 +86,6 @@ class ComicTaggerSettings:
self.show_disclaimer = True
self.dont_notify_about_this_version = ""
self.ask_about_usage_stats = True
self.hide_rename_message = False
# filename parsing settings
self.parse_scan_info = True
@ -120,7 +119,6 @@ class ComicTaggerSettings:
self.rename_extension_based_on_archive = True
self.rename_dir = ""
self.rename_move_dir = False
self.rename_new_renamer = False
self.rename_strict = False
# Auto-tag stickies
@ -161,7 +159,6 @@ class ComicTaggerSettings:
self.show_disclaimer = True
self.dont_notify_about_this_version = ""
self.ask_about_usage_stats = True
self.hide_rename_message = False
# filename parsing settings
self.parse_scan_info = True
@ -195,7 +192,6 @@ class ComicTaggerSettings:
self.rename_extension_based_on_archive = True
self.rename_dir = ""
self.rename_move_dir = False
self.rename_new_renamer = False
self.rename_strict = False
# Auto-tag stickies
@ -302,8 +298,6 @@ class ComicTaggerSettings:
self.dont_notify_about_this_version = self.config.get("dialogflags", "dont_notify_about_this_version")
if self.config.has_option("dialogflags", "ask_about_usage_stats"):
self.ask_about_usage_stats = self.config.getboolean("dialogflags", "ask_about_usage_stats")
if self.config.has_option("dialogflags", "hide_rename_message"):
self.hide_rename_message = self.config.getboolean("dialogflags", "hide_rename_message")
if self.config.has_option("comicvine", "use_series_start_as_volume"):
self.use_series_start_as_volume = self.config.getboolean("comicvine", "use_series_start_as_volume")
@ -363,8 +357,6 @@ class ComicTaggerSettings:
self.rename_dir = self.config.get("rename", "rename_dir")
if self.config.has_option("rename", "rename_move_dir"):
self.rename_move_dir = self.config.getboolean("rename", "rename_move_dir")
if self.config.has_option("rename", "rename_new_renamer"):
self.rename_new_renamer = self.config.getboolean("rename", "rename_new_renamer")
if self.config.has_option("rename", "rename_strict"):
self.rename_strict = self.config.getboolean("rename", "rename_strict")
@ -423,7 +415,6 @@ class ComicTaggerSettings:
self.config.set("dialogflags", "show_disclaimer", self.show_disclaimer)
self.config.set("dialogflags", "dont_notify_about_this_version", self.dont_notify_about_this_version)
self.config.set("dialogflags", "ask_about_usage_stats", self.ask_about_usage_stats)
self.config.set("dialogflags", "hide_rename_message", self.hide_rename_message)
if not self.config.has_section("filenameparser"):
self.config.add_section("filenameparser")
@ -467,7 +458,6 @@ class ComicTaggerSettings:
self.config.set("rename", "rename_extension_based_on_archive", self.rename_extension_based_on_archive)
self.config.set("rename", "rename_dir", self.rename_dir)
self.config.set("rename", "rename_move_dir", self.rename_move_dir)
self.config.set("rename", "rename_new_renamer", self.rename_new_renamer)
self.config.set("rename", "rename_strict", self.rename_strict)
if not self.config.has_section("autotag"):

View File

@ -17,7 +17,6 @@
import logging
import os
import platform
import re
from PyQt5 import QtCore, QtGui, QtWidgets, uic
@ -25,7 +24,7 @@ from comicapi import utils
from comicapi.genericmetadata import md_test
from comictaggerlib.comicvinecacher import ComicVineCacher
from comictaggerlib.comicvinetalker import ComicVineTalker
from comictaggerlib.filerenamer import FileRenamer, FileRenamer2
from comictaggerlib.filerenamer import FileRenamer
from comictaggerlib.imagefetcher import ImageFetcher
from comictaggerlib.settings import ComicTaggerSettings
@ -57,24 +56,8 @@ macRarHelp = """
</p>Once homebrew is installed, run: <b>brew install caskroom/cask/rar</b></body></html>
"""
old_template_tooltip = """
<html><head/><body><p>The template for the new filename. Accepts the following variables:</p><p>%series%<br/>%issue%<br/>%volume%<br/>%issuecount%<br/>%year%<br/>%month%<br/>%month_name%<br/>%publisher%<br/>%title%<br/>
%genre%<br/>
%language_code%<br/>
%criticalrating%<br/>
%alternateseries%<br/>
%alternatenumber%<br/>
%alternatecount%<br/>
%imprint%<br/>
%format%<br/>
%maturityrating%<br/>
%storyarc%<br/>
%seriesgroup%<br/>
%scaninfo%
</p><p>Examples:</p><p><span style=&quot; font-style:italic;&quot;>%series% %issue% (%year%)</span><br/><span style=&quot; font-style:italic;&quot;>%series% #%issue% - %title%</span></p></body></html>
"""
new_template_tooltip = """
template_tooltip = """
<pre>The template for the new filename. Uses python format strings https://docs.python.org/3/library/string.html#format-string-syntax
Accepts the following variables:
{is_empty} (boolean)
@ -185,19 +168,11 @@ class SettingsWindow(QtWidgets.QDialog):
validator = QtGui.QIntValidator(0, 99, self)
self.leNameLengthDeltaThresh.setValidator(validator)
new_rename = self.settings.rename_new_renamer
self.cbxNewRenamer.setChecked(new_rename)
self.cbxMoveFiles.setEnabled(new_rename)
self.leDirectory.setEnabled(new_rename)
self.lblDirectory.setEnabled(new_rename)
if self.settings.rename_new_renamer:
self.leRenameTemplate.setToolTip(new_template_tooltip)
self.leRenameTemplate.setToolTip(template_tooltip)
self.settings_to_form()
self.rename_error = None
self.rename_test()
self.cbxNewRenamer.clicked.connect(self.new_rename_toggle)
self.btnBrowseRar.clicked.connect(self.select_rar)
self.btnClearCache.clicked.connect(self.clear_cache)
self.btnResetSettings.clicked.connect(self.reset_settings)
@ -208,27 +183,12 @@ class SettingsWindow(QtWidgets.QDialog):
self.cbxRenameStrict.clicked.connect(self.rename_test)
self.leDirectory.textEdited.connect(self.rename_test)
def new_rename_toggle(self):
new_rename = self.cbxNewRenamer.isChecked()
if new_rename:
self.leRenameTemplate.setText(re.sub(r"%(\w+)%", r"{\1}", self.leRenameTemplate.text()))
self.leRenameTemplate.setToolTip(new_template_tooltip)
else:
self.leRenameTemplate.setText(re.sub(r"{(\w+)}", r"%\1%", self.leRenameTemplate.text()))
self.leRenameTemplate.setToolTip(old_template_tooltip)
self.cbxMoveFiles.setEnabled(new_rename)
self.leDirectory.setEnabled(new_rename)
self.lblDirectory.setEnabled(new_rename)
self.rename_test()
def rename_test(self):
self.rename__test(self.leRenameTemplate.text())
def rename__test(self, template):
fr = FileRenamer(md_test)
if self.cbxNewRenamer.isChecked():
fr = FileRenamer2(md_test, platform="universal" if self.cbxRenameStrict.isChecked() else "auto")
fr.move = self.cbxMoveFiles.isChecked()
fr = FileRenamer(md_test, platform="universal" if self.cbxRenameStrict.isChecked() else "auto")
fr.move = self.cbxMoveFiles.isChecked()
fr.set_template(template)
fr.set_issue_zero_padding(int(self.leIssueNumPadding.text()))
fr.set_smart_cleanup(self.cbxSmartCleanup.isChecked())
@ -360,7 +320,6 @@ class SettingsWindow(QtWidgets.QDialog):
self.settings.rename_move_dir = self.cbxMoveFiles.isChecked()
self.settings.rename_dir = self.leDirectory.text()
self.settings.rename_new_renamer = self.cbxNewRenamer.isChecked()
self.settings.rename_strict = self.cbxRenameStrict.isChecked()
self.settings.save()
@ -415,8 +374,6 @@ class SettingsWindow(QtWidgets.QDialog):
def show_template_help(self):
template_help_win = TemplateHelpWindow(self)
template_help_win.setModal(False)
if not self.cbxNewRenamer.isChecked():
template_help_win.textEdit.setHtml(old_template_tooltip)
template_help_win.show()

View File

@ -246,15 +246,6 @@ Have fun!
""",
)
self.settings.show_disclaimer = not checked
if not self.settings.hide_rename_message:
self.settings.hide_rename_message = OptionalMessageDialog.msg(
self,
"New rename template!",
"There is a new rename template format available. "
"Please use the settings window to enable and test if you use this feature.<br><br>"
"The old rename template format will be removed in the next release, "
"please reference the template help button in the settings or <a href='https://github.com/comictagger/comictagger/wiki/UserGuide#rename'>https://github.com/comictagger/comictagger/wiki/UserGuide#rename</a>",
)
if self.settings.check_for_new_version:
# self.checkLatestVersionOnline()

View File

@ -554,24 +554,7 @@
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="leRenameTemplate">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The template for the new filename. Accepts the following variables:&lt;/p&gt;&lt;p&gt;%series%&lt;br/&gt;%issue%&lt;br/&gt;%volume%&lt;br/&gt;%issuecount%&lt;br/&gt;%year%&lt;br/&gt;%month%&lt;br/&gt;%month_name%&lt;br/&gt;%publisher%&lt;br/&gt;%title%&lt;br/&gt;
%genre%&lt;br/&gt;
%language_code%&lt;br/&gt;
%criticalrating%&lt;br/&gt;
%alternateseries%&lt;br/&gt;
%alternatenumber%&lt;br/&gt;
%alternatecount%&lt;br/&gt;
%imprint%&lt;br/&gt;
%format%&lt;br/&gt;
%maturityrating%&lt;br/&gt;
%storyarc%&lt;br/&gt;
%seriesgroup%&lt;br/&gt;
%scaninfo%
&lt;/p&gt;&lt;p&gt;Examples:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;%series% %issue% (%year%)&lt;/span&gt;&lt;br/&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;%series% #%issue% - %title%&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
<widget class="QLineEdit" name="leRenameTemplate"/>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="btnTemplateHelp">
@ -636,13 +619,6 @@
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="cbxNewRenamer">
<property name="text">
<string>Enable the new renamer</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QCheckBox" name="cbxMoveFiles">
<property name="toolTip">

View File

@ -551,26 +551,29 @@ rnames = [
"universal",
"Cory Doctorow's Futuristic Tales of the Here and Now - Anda's Game #001 (2007).cbz",
),
pytest.param(
(
"{series}: {title} #{issue} ({year})",
False,
"Linux",
"Cory Doctorow's Futuristic Tales of the Here and Now: Anda's Game #001 (2007).cbz",
marks=pytest.mark.xfail,
),
pytest.param(
(
"{publisher}/ {series} #{issue} - {title} ({year})",
True,
"universal",
"IDW Publishing/Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game (2007).cbz",
marks=pytest.mark.xfail,
),
pytest.param(
(
"{publisher}/ {series} #{issue} - {title} ({year})",
False,
"universal",
"Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game (2007).cbz",
marks=pytest.mark.xfail,
),
(
r"{publisher}\ {series} #{issue} - {title} ({year})",
False,
"universal",
"Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game (2007).cbz",
),
(
"{series} # {issue} - {title} ({year})",
@ -578,18 +581,16 @@ rnames = [
"universal",
"Cory Doctorow's Futuristic Tales of the Here and Now # 001 - Anda's Game (2007).cbz",
),
pytest.param(
(
"{series} # {issue} - {locations} ({year})",
False,
"universal",
"Cory Doctorow's Futuristic Tales of the Here and Now # 001 - lonely cottage (2007).cbz",
marks=pytest.mark.xfail,
),
pytest.param(
(
"{series} #{issue} - {title} - {WriteR}, {EDITOR} ({year})",
False,
"universal",
"Cory Doctorow's Futuristic Tales of the Here and Now #001 - Anda's Game - Dara Naraghi, Ted Adams (2007).cbz",
marks=pytest.mark.xfail,
),
]

View File

@ -1,24 +1,15 @@
import re
import pathlib
import pytest
from filenames import rnames
from comicapi.genericmetadata import md_test
from comictaggerlib.filerenamer import FileRenamer, FileRenamer2
from comictaggerlib.filerenamer import FileRenamer
@pytest.mark.parametrize("template, move, platform, expected", rnames)
def test_rename_old(template, platform, move, expected):
_ = platform
_ = move
fr = FileRenamer(md_test)
fr.set_template(re.sub(r"{(\w+)}", r"%\1%", template))
assert fr.determine_name(".cbz") == expected
@pytest.mark.parametrize("template, move, platform, expected", rnames)
def test_rename_new(template, platform, move, expected):
fr = FileRenamer2(md_test, platform=platform)
def test_rename(template, platform, move, expected):
fr = FileRenamer(md_test, platform=platform)
fr.move = move
fr.set_template(template)
assert fr.determine_name(".cbz") == expected
assert str(pathlib.PureWindowsPath(fr.determine_name(".cbz"))) == str(pathlib.PureWindowsPath(expected))