Allow basic use of db query via JavaScript

This commit is contained in:
Martchus 2023-08-05 02:06:26 +02:00
parent dbd4e71281
commit a191aebd8a
4 changed files with 84 additions and 19 deletions

View File

@ -49,7 +49,7 @@ public Q_SLOTS:
void diag(const QString &level, const QString &message, const QString &context = QString());
int exec();
void exit(int retcode);
void exit(int retcode = 0);
QJSValue readEnvironmentVariable(const QString &variable, const QJSValue &defaultValue = QJSValue()) const;
QJSValue readDirectory(const QString &path);

View File

@ -209,6 +209,14 @@ const QByteArray *QueryResultsModel::cover(const QModelIndex &index) const
return nullptr;
}
QByteArray QueryResultsModel::coverValue(const QModelIndex &index) const
{
if (const auto *c = cover(index)) {
return *c;
}
return QByteArray();
}
/*!
* \brief Fetches the cover the specified \a index.
* \returns
@ -240,6 +248,14 @@ const QString *QueryResultsModel::lyrics(const QModelIndex &index) const
return nullptr;
}
QString QueryResultsModel::lyricsValue(const QModelIndex &index) const
{
if (const auto *l = lyrics(index)) {
return *l;
}
return QString();
}
/*!
* \brief Fetches the lyrics the specified \a index.
* \returns

View File

@ -42,6 +42,9 @@ struct SongDescription {
class QueryResultsModel : public QAbstractTableModel {
Q_OBJECT
Q_PROPERTY(QStringList errorList READ errorList)
Q_PROPERTY(bool areResultsAvailable READ areResultsAvailable)
Q_PROPERTY(bool isFetchingCover READ isFetchingCover)
public:
enum Column {
@ -68,11 +71,13 @@ public:
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
const QByteArray *cover(const QModelIndex &index) const;
virtual bool fetchCover(const QModelIndex &index);
Q_INVOKABLE QByteArray coverValue(const QModelIndex &index) const;
Q_INVOKABLE virtual bool fetchCover(const QModelIndex &index);
const QString *lyrics(const QModelIndex &index) const;
virtual bool fetchLyrics(const QModelIndex &index);
virtual void abort();
virtual QUrl webUrl(const QModelIndex &index);
Q_INVOKABLE QString lyricsValue(const QModelIndex &index) const;
Q_INVOKABLE virtual bool fetchLyrics(const QModelIndex &index);
Q_INVOKABLE virtual void abort();
Q_INVOKABLE virtual QUrl webUrl(const QModelIndex &index);
Q_SIGNALS:
void resultsAvailable();

View File

@ -21,7 +21,12 @@ function isString(value) {
return typeof(value) === "string" || value instanceof String;
}
function changeTagFields(file, tag) {
function waitFor(signal) {
signal.connect(() => { utility.exit(); });
utility.exec();
}
function logTagInfo(file, tag) {
// log tag type and supported fields
const fields = tag.fields;
utility.diag("debug", tag.type, "tag");
@ -34,8 +39,10 @@ function changeTagFields(file, tag) {
utility.diag("debug", content, key + " (" + value.type + ")");
}
}
}
// apply fixes to main text fields
function applyFixesToMainFields(file, tag) {
const fields = tag.fields;
for (const key of mainTextFields) {
for (const value of fields[key]) {
if (isString(value.content)) {
@ -45,27 +52,64 @@ function changeTagFields(file, tag) {
}
}
}
}
// ensure personal fields are cleared
function clearPersonalFields(file, tag) {
const fields = tag.fields;
for (const key of personalFields) {
fields[key] = [];
}
}
// set total number of tracks if not already assigned using the number of files in directory
const track = fields.track;
if (track.find(value => !value.content.total) !== undefined) {
const extension = file.extension;
const dirItems = utility.readDirectory(file.containingDirectory) || [];
const total = dirItems.filter(fileName => fileName.endsWith(extension)).length;
if (total) {
for (const value of track) {
value.content.total |= total;
}
}
function addTotalNumberOfTracks(file, tag) {
const track = tag.fields.track;
if (track.find(value => !value.content.total) === undefined) {
return; // skip if already assigned
}
const extension = file.extension;
const dirItems = utility.readDirectory(file.containingDirectory) || [];
const total = dirItems.filter(fileName => fileName.endsWith(extension)).length;
if (!total) {
return;
}
for (const value of track) {
value.content.total |= total;
}
}
function addLyrics(file, tag) {
const fields = tag.fields;
if (fields.lyrics.length) {
return; // skip if already assigned
}
const firstTitle = fields.title?.[0]?.content;
const firstArtist = fields.artist?.[0]?.content;
if (!firstTitle || !firstArtist) {
return;
}
const lyricsModel = utility.queryMakeItPersonal({title: firstTitle, artist: firstArtist});
if (!lyricsModel.areResultsAvailable) {
waitFor(lyricsModel.resultsAvailable);
}
if (!lyricsModel.fetchLyrics(lyricsModel.index(0, 0))) {
waitFor(lyricsModel.lyricsAvailable);
}
fields.lyrics = lyricsModel.lyricsValue(lyricsModel.index(0, 0));
}
function addMiscFields(file, tag) {
// assume the number of disks is always one for now
const fields = tag.fields;
if (!fields.disk.length) {
fields.disk = "1/1";
}
}
function changeTagFields(file, tag) {
logTagInfo(file, tag);
applyFixesToMainFields(file, tag);
clearPersonalFields(file, tag);
addTotalNumberOfTracks(file, tag);
addMiscFields(file, tag);
addLyrics(file, tag);
}