Allow renaming file via `set --script …`
This allows doing what the GUI renaming utilitiy does on the command-line. If only renaming is wanted
This commit is contained in:
parent
b5f9158106
commit
72dcbbbd81
14
README.md
14
README.md
|
@ -369,12 +369,13 @@ Here are some Bash examples which illustrate getting and setting tag information
|
|||
- The script needs to be ECMAScript as supported by the Qt framework.
|
||||
- This feature requires the tag editor to be configured with Qt QML as JavaScript provider at
|
||||
compile time. Checkout the build instructions under "Building with Qt GUI" for details.
|
||||
- The script needs to export a `main()` function. This function gets executed for every file and
|
||||
passed an object representing this file as first argument.
|
||||
- The script needs to export a `main()` function. This function is invoked for every file and
|
||||
passed an object representing the current file as first argument.
|
||||
- Checkout the file `testfiles/set-tags.js` in this repository for an example that applies basic
|
||||
fixes and tries to fetch lyrics and cover art.
|
||||
- The option `--pedantic debug` is not required but useful for debugging. You may also add
|
||||
`--script-settings dryRun=1` and use that setting within the script as shown in the example.
|
||||
- For debugging, the option `--pedantic debug` is very useful. You may also add
|
||||
`--script-settings dryRun=1` and check for that setting within the script as shown in the
|
||||
mentioned example script.
|
||||
- Common tag fields are exposed as object properties as shown in the mentioned example.
|
||||
- Only properties for fields that are supported by the tag are added to the "fields" object.
|
||||
- Adding properties of unsupported fields manually does not work; those will just be ignored.
|
||||
|
@ -394,6 +395,11 @@ Here are some Bash examples which illustrate getting and setting tag information
|
|||
- The script is executed before any other modifications are applied. So if you also specify
|
||||
values as usual (via `--values`) then these values have precedence over values set by the
|
||||
script.
|
||||
- It is also possible to rename the file (via e.g. `file.rename(newPath)`). This will be done
|
||||
immediately and also if `main()` returns a falsy value (so it is possible to only rename a
|
||||
file without modifying it by returning a falsy value). If the specified path is relative, it
|
||||
is interpreted relative to current directory of the file (and *not* to the current working
|
||||
directory of the tag editor).
|
||||
|
||||
##### Further useful commands
|
||||
* Let the tag editor return with a non-zero exit code even if only non-fatal problems have been encountered
|
||||
|
|
|
@ -494,6 +494,7 @@ public:
|
|||
private:
|
||||
static void addWarnings(Diagnostics &diag, const std::string &context, const QList<QQmlError> &warnings);
|
||||
|
||||
const SetTagInfoArgs &args;
|
||||
int argc;
|
||||
QCoreApplication app;
|
||||
Diagnostics diag;
|
||||
|
@ -510,7 +511,8 @@ private:
|
|||
* - Logs status/problems directly in accordance with other parts of the CLI.
|
||||
*/
|
||||
JavaScriptProcessor::JavaScriptProcessor(const SetTagInfoArgs &args)
|
||||
: argc(0)
|
||||
: args(args)
|
||||
, argc(0)
|
||||
, app(argc, nullptr)
|
||||
, utility(new UtilityObject(&engine))
|
||||
{
|
||||
|
@ -567,7 +569,7 @@ JavaScriptProcessor::JavaScriptProcessor(const SetTagInfoArgs &args)
|
|||
*/
|
||||
QJSValue JavaScriptProcessor::callMain(MediaFileInfo &mediaFileInfo, Diagnostics &diag)
|
||||
{
|
||||
auto fileInfoObject = MediaFileInfoObject(mediaFileInfo, diag, &engine);
|
||||
auto fileInfoObject = MediaFileInfoObject(mediaFileInfo, diag, &engine, args.quietArg.isPresent());
|
||||
auto fileInfoObjectValue = engine.newQObject(&fileInfoObject);
|
||||
auto context = argsToString("executing JavaScript for ", mediaFileInfo.fileName());
|
||||
utility->setDiag(&context, &diag);
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include <c++utilities/conversion/binaryconversion.h>
|
||||
#include <c++utilities/conversion/conversionexception.h>
|
||||
#include <c++utilities/conversion/stringbuilder.h>
|
||||
#include <c++utilities/io/path.h>
|
||||
|
||||
#include <qtutilities/misc/compat.h>
|
||||
|
||||
|
@ -33,6 +35,7 @@
|
|||
#include <QJSValueIterator>
|
||||
#include <QRegularExpression>
|
||||
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
@ -558,11 +561,13 @@ void TagObject::applyChanges()
|
|||
}
|
||||
}
|
||||
|
||||
MediaFileInfoObject::MediaFileInfoObject(TagParser::MediaFileInfo &mediaFileInfo, TagParser::Diagnostics &diag, QJSEngine *engine, QObject *parent)
|
||||
MediaFileInfoObject::MediaFileInfoObject(
|
||||
TagParser::MediaFileInfo &mediaFileInfo, TagParser::Diagnostics &diag, QJSEngine *engine, bool quiet, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_f(mediaFileInfo)
|
||||
, m_diag(diag)
|
||||
, m_engine(engine)
|
||||
, m_quiet(quiet)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -621,4 +626,27 @@ void MediaFileInfoObject::applyChanges()
|
|||
}
|
||||
}
|
||||
|
||||
bool MediaFileInfoObject::rename(const QString &newPath)
|
||||
{
|
||||
const auto from = m_f.path();
|
||||
const auto fromNative = std::filesystem::path(CppUtilities::makeNativePath(from));
|
||||
const auto toRelUtf8 = newPath.toUtf8();
|
||||
const auto toRelView = CppUtilities::PathStringView(toRelUtf8.data(), static_cast<std::size_t>(toRelUtf8.size()));
|
||||
const auto toNative = fromNative.parent_path().append(CppUtilities::makeNativePath(toRelView));
|
||||
const auto toView = CppUtilities::extractNativePath(toNative.native());
|
||||
try {
|
||||
m_f.stream().close();
|
||||
std::filesystem::rename(fromNative, toNative);
|
||||
m_f.reportPathChanged(toView);
|
||||
m_f.stream().open(m_f.path(), std::ios_base::in | std::ios_base::out | std::ios_base::binary);
|
||||
} catch (const std::runtime_error &e) {
|
||||
m_diag.emplace_back(TagParser::DiagLevel::Critical, e.what(), CppUtilities::argsToString("renaming \"", from, "\" to \"", toView));
|
||||
return false;
|
||||
}
|
||||
if (!m_quiet) {
|
||||
std::cout << " - Renamed \"" << from << "\" to \"" << toView << "\"\n";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Cli
|
||||
|
|
|
@ -193,7 +193,8 @@ class MediaFileInfoObject : public QObject {
|
|||
Q_PROPERTY(QList<TagObject *> tags READ tags)
|
||||
|
||||
public:
|
||||
explicit MediaFileInfoObject(TagParser::MediaFileInfo &mediaFileInfo, TagParser::Diagnostics &diag, QJSEngine *engine, QObject *parent = nullptr);
|
||||
explicit MediaFileInfoObject(
|
||||
TagParser::MediaFileInfo &mediaFileInfo, TagParser::Diagnostics &diag, QJSEngine *engine, bool quiet, QObject *parent = nullptr);
|
||||
~MediaFileInfoObject() override;
|
||||
|
||||
TagParser::MediaFileInfo &fileInfo();
|
||||
|
@ -207,12 +208,14 @@ public:
|
|||
|
||||
public Q_SLOTS:
|
||||
void applyChanges();
|
||||
bool rename(const QString &newPath);
|
||||
|
||||
private:
|
||||
TagParser::MediaFileInfo &m_f;
|
||||
TagParser::Diagnostics &m_diag;
|
||||
QJSEngine *m_engine;
|
||||
QList<TagObject *> m_tags;
|
||||
bool m_quiet;
|
||||
};
|
||||
|
||||
inline TagParser::MediaFileInfo &MediaFileInfoObject::fileInfo()
|
||||
|
|
Loading…
Reference in New Issue