Improve renaming utility

* Improve UI
* Add simple example script (the current example script grew quite big and
  is likely not good to get started)
* Add script to format example scripts
This commit is contained in:
Martchus 2020-11-25 18:05:23 +01:00
parent b0cd798ec1
commit 596d67387f
8 changed files with 107 additions and 34 deletions

View File

@ -54,10 +54,11 @@ RenameFilesDialog::RenameFilesDialog(QWidget *parent)
m_ui->notificationLabel->setHidden(true);
// setup pasteScriptButton menu
QMenu *pasteScriptButtonMenu = new QMenu(m_ui->pasteScriptPushButton);
pasteScriptButtonMenu->addAction(tr("from file"), this, &RenameFilesDialog::showSelectScriptFileDlg);
pasteScriptButtonMenu->addAction(tr("from clipboard"), this, &RenameFilesDialog::pasteScriptFromClipboard);
pasteScriptButtonMenu->addAction(tr("default script"), this, &RenameFilesDialog::pasteDefaultExampleScript);
auto *const pasteScriptButtonMenu = new QMenu(m_ui->pasteScriptPushButton);
pasteScriptButtonMenu->addAction(tr("File"), this, &RenameFilesDialog::showSelectScriptFileDlg);
pasteScriptButtonMenu->addAction(tr("Paste from clipboard"), this, &RenameFilesDialog::pasteScriptFromClipboard);
pasteScriptButtonMenu->addAction(tr("Simple example"), this, &RenameFilesDialog::pasteSimpleExampleScript);
pasteScriptButtonMenu->addAction(tr("Advanced example"), this, &RenameFilesDialog::pasteAdvancedExampleScript);
m_ui->pasteScriptPushButton->setMenu(pasteScriptButtonMenu);
// setup icons
@ -76,7 +77,7 @@ RenameFilesDialog::RenameFilesDialog(QWidget *parent)
m_ui->javaScriptPlainTextEdit->setPlainText(settings.editorScript);
m_scriptModified = true;
} else {
pasteDefaultExampleScript();
pasteSimpleExampleScript();
}
// connect signals and slots
@ -354,9 +355,14 @@ void RenameFilesDialog::pasteScriptFromClipboard()
m_ui->javaScriptPlainTextEdit->setPlainText(script);
}
void RenameFilesDialog::pasteDefaultExampleScript()
void RenameFilesDialog::pasteSimpleExampleScript()
{
pasteScriptFromFile(QStringLiteral(":/scripts/renamefiles/example1"));
pasteScriptFromFile(QStringLiteral(":/scripts/renamefiles/simple-example"));
}
void RenameFilesDialog::pasteAdvancedExampleScript()
{
pasteScriptFromFile(QStringLiteral(":/scripts/renamefiles/advanced-example"));
}
void RenameFilesDialog::showTreeViewContextMenu(const QPoint &position)

View File

@ -45,7 +45,8 @@ private Q_SLOTS:
void previewItemSelected(const QItemSelection &selected, const QItemSelection &deselected);
void pasteScriptFromFile(const QString &fileName);
void pasteScriptFromClipboard();
void pasteDefaultExampleScript();
void pasteSimpleExampleScript();
void pasteAdvancedExampleScript();
void showTreeViewContextMenu(const QPoint &position);
void showSelectScriptFileDlg();
void abortClose();

View File

@ -98,7 +98,7 @@
<item>
<widget class="QPushButton" name="pasteScriptPushButton">
<property name="text">
<string>Paste</string>
<string>Open/Examples</string>
</property>
<property name="icon">
<iconset theme="edit-paste">
@ -578,7 +578,7 @@
<item>
<widget class="PathLineEdit" name="scriptFilePathLineEdit">
<property name="placeholderText">
<string>select a script file</string>
<string>Select a script file</string>
</property>
</widget>
</item>

View File

@ -1,5 +1,6 @@
<RCC>
<qresource prefix="/scripts/renamefiles">
<file alias="example1">scripts/renamefiles/example1.js</file>
<file alias="simple-example">scripts/renamefiles/simple-example.js</file>
<file alias="advanced-example">scripts/renamefiles/advanced-example.js</file>
</qresource>
</RCC>

View File

@ -0,0 +1,27 @@
{
"indent_size": 4,
"indent_char": " ",
"indent_with_tabs": false,
"editorconfig": false,
"eol": "\n",
"end_with_newline": false,
"indent_level": 0,
"preserve_newlines": true,
"max_preserve_newlines": 10,
"space_in_paren": false,
"space_in_empty_paren": false,
"jslint_happy": true,
"space_after_anon_function": false,
"space_after_named_function": false,
"brace_style": "collapse",
"unindent_chained_methods": false,
"break_chained_methods": false,
"keep_array_indentation": false,
"unescape_strings": false,
"wrap_line_length": 0,
"e4x": false,
"comma_first": false,
"operator_position": "before-newline",
"indent_empty_lines": false,
"templating": ["auto"]
}

View File

@ -18,7 +18,7 @@ var keepTitleFromFileName = false
// specifies whether track information should be appended (like [H.265-320p AAC-LC-2ch-eng AAC-LC-2ch-ger])
var includeTrackInfo = false
// specifies the "distribution directory"
//var distDir = false; // don't move files around
//var distDir = false // don't move files around
var distDir = "/path/to/my/music-collection" // move files to an appropriate subdirectory under this path
// directory used to store collections which contain songs from multiple artists
var collectionsDir = "collections"
@ -59,16 +59,16 @@ function appropriateDigitCount(pos, total) {
// returns a copy of the specified \a name with characters that might be avoided in file names striped out
function validFileName(name) {
return name !== undefined ? name.replace(/[\/\\]/gi, " - ").replace(
/[<>?!*|:\"\n\f\r]/gi, "") : ""
/[<>?!*|:\"\n\f\r]/gi, "") : ""
}
// returns a copy of the specified \a name with characters that might be avoided in directory names striped out.
function validDirectoryName(name) {
return name !== undefined ? name.replace(/[\/\\]/gi, " - ").replace(
/[<>?!*|:\".\n\f\r]/gi, "") : ""
/[<>?!*|:\".\n\f\r]/gi, "") : ""
}
// strips tags from the beginning or end of the string if configured
function tagsStripped(name) {
return stripTags ? name.replace(/^(\[[^\]]*\]\s*)+/g, "").replace(/(\s*\[[^\]]*\])+$/g, "") : name;
return stripTags ? name.replace(/^(\[[^\]]*\]\s*)+/g, "").replace(/(\s*\[[^\]]*\])+$/g, "") : name
}
//
@ -90,26 +90,26 @@ var tracks = fileInfo.tracks
var infoFromFileName = tageditor.parseFileName(fileInfo.currentBaseName)
// skip hidden and "desktop.ini" files
if (fileInfo.currentName.indexOf(".") === 0
|| fileInfo.currentName === "desktop.ini") {
if (fileInfo.currentName.indexOf(".") === 0 ||
fileInfo.currentName === "desktop.ini") {
tageditor.skip()
return
}
// treat *.lrc files like their corresponding audio files
var keepSuffix;
var keepSuffix
if (fileInfo.currentSuffix === "lrc") {
keepSuffix = fileInfo.currentSuffix; // keep the lrc suffix later
for(let extension of ["mp3", "flac", "m4a"]) {
fileInfo = tageditor.parseFileInfo(fileInfo.currentPathWithoutExtension + "." + extension);
tag = fileInfo.tag;
keepSuffix = fileInfo.currentSuffix // keep the lrc suffix later
for (let extension of ["mp3", "flac", "m4a"]) {
fileInfo = tageditor.parseFileInfo(fileInfo.currentPathWithoutExtension + "." + extension)
tag = fileInfo.tag
if (!fileInfo.ioErrorOccured) {
break;
break
}
}
if (fileInfo.ioErrorOccured) {
tageditor.skip("skipping, corresponding audio file not present");
return;
tageditor.skip("skipping, corresponding audio file not present")
return
}
}
@ -133,10 +133,7 @@ if (fileInfo.currentSuffix === "tmp") {
var fields = []
// get the artist (preferably album artist), remove invalid characters and add it to fields array
var artist = validFileName(tag.albumartist)
if (artist.length === 0) {
artist = validFileName(tag.artist)
}
var artist = validFileName(tag.albumartist || tag.artist)
if (includeArtist && !isPartOfCollection(tag) && notEmpty(artist)) {
fields.push(artist)
}
@ -214,10 +211,7 @@ if (!distDir) {
return
}
var path = [distDir]
var artist = validDirectoryName(tag.albumartist)
if (artist.length === 0) {
artist = validDirectoryName(tag.artist)
}
var artist = validDirectoryName(tag.albumartist || tag.artist)
if (isPartOfCollection(tag)) {
path.push(collectionsDir)
} else if (isMiscFile(tag)) {
@ -241,4 +235,4 @@ if (tag.diskTotal >= 2) {
path.push("Disk " + appropriateDigitCount(tag.diskPos, tag.diskTotal))
}
// apply new relative directory
tageditor.move(path.join("/"))
tageditor.move(path.join("/"))

View File

@ -0,0 +1,6 @@
#!/bin/bash
set -e
for js_file in *.js; do
js-beautify --jslint-happy -r "$js_file"
done

View File

@ -0,0 +1,38 @@
// This is a simple example script demonstrating how the renaming tool can be used.
// script configuration
// skip directories in this example script
if (!tageditor.isFile) {
tageditor.skip()
return
}
// parse file using the built-in parseFileInfo function
const fileInfo = tageditor.parseFileInfo(tageditor.currentPath)
const tag = fileInfo.tag
const tracks = fileInfo.tracks
// deduce title and track number from the file name using the built-in parseFileName function (as fallback if tags missing)
const infoFromFileName = tageditor.parseFileName(fileInfo.currentBaseName)
// skip files which don't contain audio or video tracks
if (!fileInfo.hasAudioTracks && !fileInfo.hasVideoTracks) {
tageditor.skip()
return
}
// make new filename
const fieldsToInclude = [tag.albumartist || tag.artist, tag.album, tag.trackPos || infoFromFileName.trackPos, tag.title || infoFromFileName.title]
let newName = ""
for (let field of fieldsToInclude) {
if (typeof field === "number") {
for (field = field + "", count = (tag.trackTotal + "").length; field.length < count; field = "0" + field);
}
if (field && field.length !== 0) {
newName = newName.concat(newName.length === 0 ? "" : " - ", field)
}
}
newName = newName.concat(".", fileInfo.suitableSuffix || fileInfo.currentSuffix)
// apply new name
tageditor.rename(newName)