diff --git a/renamingutility/filesystemitem.cpp b/renamingutility/filesystemitem.cpp index a1a94ee..9fcf96b 100644 --- a/renamingutility/filesystemitem.cpp +++ b/renamingutility/filesystemitem.cpp @@ -34,7 +34,7 @@ FileSystemItem::FileSystemItem(ItemStatus status, ItemType type, const QString & FileSystemItem::~FileSystemItem() { - for (FileSystemItem *child : m_children) { + for (auto *const child : m_children) { child->m_parent = nullptr; delete child; } @@ -45,14 +45,15 @@ FileSystemItem::~FileSystemItem() void FileSystemItem::setParent(FileSystemItem *parent) { - if (parent != m_parent) { - if (m_parent) { - m_parent->m_children.removeAll(this); - } - m_parent = parent; - if (m_parent && !m_parent->m_children.contains(this)) { - m_parent->m_children << this; - } + if (parent == m_parent) { + return; + } + if (m_parent) { + m_parent->m_children.removeAll(this); + } + m_parent = parent; + if (m_parent && !m_parent->m_children.contains(this)) { + m_parent->m_children << this; } } @@ -100,19 +101,16 @@ bool FileSystemItem::setNewName(const QString &newName) { switch (m_status) { case ItemStatus::Current: - if (!m_counterpart) { - if (m_parent) { - m_counterpart = new FileSystemItem(ItemStatus::New, m_type, newName); - m_counterpart->m_counterpart = this; - m_counterpart->setParent(m_parent); - } else { - // parent required - return false; - } - } else { + if (m_counterpart) { m_counterpart->setName(newName); + return true; } - return true; + if (m_parent) { + m_counterpart = new FileSystemItem(ItemStatus::New, m_type, newName, m_parent); + m_counterpart->m_counterpart = this; + return true; + } + return false; case ItemStatus::New: setName(newName); return true; @@ -122,7 +120,7 @@ bool FileSystemItem::setNewName(const QString &newName) FileSystemItem *FileSystemItem::findChild(const QString &name) const { - for (FileSystemItem *child : m_children) { + for (auto *const child : m_children) { if (child->name() == name) { return child; } @@ -132,7 +130,7 @@ FileSystemItem *FileSystemItem::findChild(const QString &name) const FileSystemItem *FileSystemItem::findChild(const QString &name, const FileSystemItem *exclude) const { - for (FileSystemItem *child : m_children) { + for (auto *const child : m_children) { if (child != exclude && child->name() == name) { return child; } @@ -142,23 +140,24 @@ FileSystemItem *FileSystemItem::findChild(const QString &name, const FileSystemI FileSystemItem *FileSystemItem::makeChildAvailable(const QString &relativePath) { - QStringList dirs = relativePath.split(QDir::separator(), QString::SkipEmptyParts); - FileSystemItem *parent = this; - if (!dirs.isEmpty()) { - if (relativePath.startsWith(QChar('/'))) { - // we actually just got an absolute path - // -> just leave the / there to handle absolute path as well - dirs.front().prepend(QChar('/')); - } - for (const QString &dir : dirs) { - FileSystemItem *child = parent->findChild(dir); - if (!child) { - child = new FileSystemItem(ItemStatus::New, ItemType::Dir, dir); - child->setParent(parent); - child->setNote(QCoreApplication::translate("RenamingUtility::FileSystemItem", "will be created")); - } - parent = child; + auto dirs = relativePath.split(QDir::separator(), QString::SkipEmptyParts); + if (dirs.isEmpty()) { + return this; + } + + auto *parent = this; + if (relativePath.startsWith(QChar('/'))) { + // we actually just got an absolute path + // -> just leave the / there to handle absolute path as well + dirs.front().prepend(QChar('/')); + } + for (const QString &dir : dirs) { + auto *child = parent->findChild(dir); + if (!child) { + child = new FileSystemItem(ItemStatus::New, ItemType::Dir, dir, parent); + child->setNote(QCoreApplication::translate("RenamingUtility::FileSystemItem", "will be created")); } + parent = child; } return parent; } @@ -179,13 +178,14 @@ QString FileSystemItem::relativeDir() const void FileSystemItem::relativePath(QString &res) const { - if (m_parent) { - m_parent->relativePath(res); - if (!res.isEmpty()) { - res.append(QLatin1Char('/')); - } - res.append(name()); + if (!m_parent) { + return; } + m_parent->relativePath(res); + if (!res.isEmpty()) { + res.append(QLatin1Char('/')); + } + res.append(name()); } QString FileSystemItem::relativePath() const @@ -197,17 +197,16 @@ QString FileSystemItem::relativePath() const bool FileSystemItem::hasSibling(const QString &name) const { - if (m_parent) { - const QList &siblings = m_parent->children(); - for (const FileSystemItem *siblingItem : siblings) { - if (siblingItem == this) { - continue; - } - if (!siblingItem->newName().isEmpty() && siblingItem->newName() == name) { - return true; - } else if (siblingItem->name() == name) { - return true; - } + if (!m_parent) { + return false; + } + const auto &siblings = m_parent->children(); + for (const auto *const siblingItem : siblings) { + if (siblingItem == this) { + continue; + } + if ((!siblingItem->newName().isEmpty() && siblingItem->newName() == name) || siblingItem->name() == name) { + return true; } } return false; diff --git a/renamingutility/filesystemitem.h b/renamingutility/filesystemitem.h index 5c0b2ed..94cb3bc 100644 --- a/renamingutility/filesystemitem.h +++ b/renamingutility/filesystemitem.h @@ -48,7 +48,7 @@ public: void setChecked(bool checked); bool checkable() const; void setCheckable(bool checkable); - int row(); + int row() const; void relativeDir(QString &res) const; QString relativeDir() const; void relativePath(QString &res) const; @@ -186,9 +186,9 @@ inline void FileSystemItem::setCheckable(bool checkable) m_checkable = checkable; } -inline int FileSystemItem::row() +inline int FileSystemItem::row() const { - return m_parent ? m_parent->children().indexOf(this) : -1; + return m_parent ? m_parent->children().indexOf(const_cast(this)) : -1; } } // namespace RenamingUtility diff --git a/renamingutility/filesystemitemmodel.cpp b/renamingutility/filesystemitemmodel.cpp index 218f8a5..0ac4de5 100644 --- a/renamingutility/filesystemitemmodel.cpp +++ b/renamingutility/filesystemitemmodel.cpp @@ -23,119 +23,126 @@ FileSystemItemModel::FileSystemItemModel(FileSystemItem *rootItem, QObject *pare { } -FileSystemItemModel::~FileSystemItemModel() -{ -} - void FileSystemItemModel::setRootItem(FileSystemItem *rootItem) { - if (m_rootItem != rootItem) { - beginResetModel(); - m_rootItem = rootItem; - endResetModel(); + if (m_rootItem == rootItem) { + return; } + beginResetModel(); + m_rootItem = rootItem; + endResetModel(); +} + +FileSystemItem *FileSystemItemModel::fileSystemItemFromIndex(const QModelIndex &index) +{ + return index.isValid() ? reinterpret_cast(index.internalPointer()) : nullptr; +} + +const FileSystemItem *FileSystemItemModel::fileSystemItemFromIndex(const QModelIndex &index) const +{ + return const_cast(this)->fileSystemItemFromIndex(index); } QVariant FileSystemItemModel::data(const QModelIndex &index, int role) const { - if (index.isValid()) { - if (FileSystemItem *item = reinterpret_cast(index.internalPointer())) { - switch (role) { - case Qt::DisplayRole: - switch (index.column()) { - case 0: - switch (item->status()) { - case ItemStatus::Current: - return item->name(); - case ItemStatus::New: - return item->counterpart() ? item->counterpart()->name() : item->name(); - } - break; - case 1: - switch (item->status()) { - case ItemStatus::Current: - return item->counterpart() ? item->counterpart()->name() : item->name(); - case ItemStatus::New: - return item->name(); - } - break; - case 2: - return item->note(); - default:; - } - break; - case Qt::DecorationRole: - switch (index.column()) { - case 0: - case 1: - switch (item->type()) { - case ItemType::Dir: - return QApplication::style()->standardIcon(QStyle::SP_DirIcon); - default:; - } - break; - default:; - } - break; - case Qt::FontRole: { - QFont font; - if ((index.column() == 0 && item->status() == ItemStatus::New && !item->counterpart()) - || (index.column() == 1 && item->status() == ItemStatus::Current && !item->counterpart())) { - font.setItalic(true); - } - return font; + const auto *const item = fileSystemItemFromIndex(index); + if (!item) { + return QVariant(); + } + switch (role) { + case Qt::DisplayRole: + switch (index.column()) { + case 0: + switch (item->status()) { + case ItemStatus::Current: + return item->name(); + case ItemStatus::New: + return item->counterpart() ? item->counterpart()->name() : item->name(); } - case Qt::ForegroundRole: - if (item->errorOccured()) { - return QBrush(Qt::red); - } else if (item->applied()) { - return QBrush(Qt::darkGreen); - } else if ((index.column() == 0 && item->status() == ItemStatus::New && !item->counterpart()) - || (index.column() == 1 && item->status() == ItemStatus::Current && !item->counterpart())) { - return QBrush(Qt::gray); - } - break; - case ErrorStatusRole: - return item->errorOccured(); + break; + case 1: + switch (item->status()) { + case ItemStatus::Current: + return item->counterpart() ? item->counterpart()->name() : item->name(); + case ItemStatus::New: + return item->name(); + } + break; + case 2: + return item->note(); + default:; + } + break; + case Qt::DecorationRole: + switch (index.column()) { + case 0: + case 1: + switch (item->type()) { + case ItemType::Dir: + return QApplication::style()->standardIcon(QStyle::SP_DirIcon); default:; } + break; + default:; } + break; + case Qt::FontRole: { + QFont font; + if ((index.column() == 0 && item->status() == ItemStatus::New && !item->counterpart()) + || (index.column() == 1 && item->status() == ItemStatus::Current && !item->counterpart())) { + font.setItalic(true); + } + return font; + } + case Qt::ForegroundRole: + if (item->errorOccured()) { + return QBrush(Qt::red); + } else if (item->applied()) { + return QBrush(Qt::darkGreen); + } else if ((index.column() == 0 && item->status() == ItemStatus::New && !item->counterpart()) + || (index.column() == 1 && item->status() == ItemStatus::Current && !item->counterpart())) { + return QBrush(Qt::gray); + } + break; + case ErrorStatusRole: + return item->errorOccured(); + default:; } return QVariant(); } bool FileSystemItemModel::setData(const QModelIndex &index, const QVariant &value, int role) { - if (index.isValid()) { - if (FileSystemItem *item = reinterpret_cast(index.internalPointer())) { - switch (role) { - case Qt::DisplayRole: - switch (index.column()) { - case 0: - if (item->setCurrentName(value.toString())) { - emit dataChanged(index, index, QVector() << role); - return true; - } else { - return false; - } - case 1: - item->setNewName(value.toString()); - emit dataChanged(index, index, QVector() << role); - return true; - case 2: - item->setNote(value.toString()); - emit dataChanged(index, index, QVector() << role); - return true; - default:; - } - break; - case ErrorStatusRole: - item->setErrorOccured(value.toBool()); - emit dataChanged(index, index, QVector() << role << Qt::DecorationRole); + auto *const item = fileSystemItemFromIndex(index); + if (!item) { + return false; + } + switch (role) { + case Qt::DisplayRole: + switch (index.column()) { + case 0: + if (item->setCurrentName(value.toString())) { + emit dataChanged(index, index, QVector() << role); return true; - default:; + } else { + return false; } + case 1: + item->setNewName(value.toString()); + emit dataChanged(index, index, QVector() << role); + return true; + case 2: + item->setNote(value.toString()); + emit dataChanged(index, index, QVector() << role); + return true; + default:; } + break; + case ErrorStatusRole: + item->setErrorOccured(value.toBool()); + emit dataChanged(index, index, QVector() << role << Qt::DecorationRole); + return true; + default:; } return false; } @@ -152,7 +159,7 @@ QVariant FileSystemItemModel::headerData(int section, Qt::Orientation orientatio case 1: return tr("New name"); case 2: - return tr("Notes"); + return tr("Note"); default:; } break; @@ -166,32 +173,32 @@ QVariant FileSystemItemModel::headerData(int section, Qt::Orientation orientatio QModelIndex FileSystemItemModel::index(int row, int column, const QModelIndex &parent) const { - if (FileSystemItem *parentItem = parent.isValid() ? reinterpret_cast(parent.internalPointer()) : m_rootItem) { - const QList &children = parentItem->children(); - if (row < children.length()) { - return createIndex(row, column, children.at(row)); - } + const auto *const parentItem = parent.isValid() ? reinterpret_cast(parent.internalPointer()) : m_rootItem; + if (!parentItem) { + return QModelIndex(); } - return QModelIndex(); + const auto &children = parentItem->children(); + return row < children.size() ? createIndex(row, column, children.at(row)) : QModelIndex(); } QModelIndex FileSystemItemModel::index(FileSystemItem *item, int column) const { forward_list path; path.push_front(item); - FileSystemItem *parent = item->parent(); + auto *parent = item->parent(); while (parent) { path.push_front(parent); parent = parent->parent(); } - if (path.front() == m_rootItem) { - path.pop_front(); - QModelIndex index; - for (FileSystemItem *pathItem : path) { - index = this->index(pathItem->row(), column, index); - if (pathItem == item || !index.isValid()) { - return index; - } + if (path.front() != m_rootItem) { + return QModelIndex(); + } + path.pop_front(); + QModelIndex index; + for (auto *const pathItem : path) { + index = this->index(pathItem->row(), column, index); + if (pathItem == item || !index.isValid()) { + return index; } } return QModelIndex(); @@ -199,35 +206,32 @@ QModelIndex FileSystemItemModel::index(FileSystemItem *item, int column) const QModelIndex FileSystemItemModel::parent(const QModelIndex &index) const { - if (index.isValid()) { - if (FileSystemItem *item = reinterpret_cast(index.internalPointer())) { - FileSystemItem *parent = item->parent(); - if (parent && (index.row() < parent->children().length())) { - return createIndex(parent->row(), index.column(), parent); - } - } + const auto *const item = fileSystemItemFromIndex(index); + if (!item) { + return QModelIndex(); } - return QModelIndex(); + auto *const parent = item->parent(); + if (!parent || index.row() >= parent->children().size()) { + return QModelIndex(); + } + return createIndex(parent->row(), index.column(), parent); } QModelIndex FileSystemItemModel::counterpart(const QModelIndex &index, int column = -1) { - if (index.isValid()) { - if (column < 0) { - column = index.column(); - } - if (FileSystemItem *item = reinterpret_cast(index.internalPointer())) { - if (item->counterpart()) { - return this->index(item->counterpart(), column); - } - } + const auto *const item = fileSystemItemFromIndex(index); + if (!item) { + return QModelIndex(); } - return QModelIndex(); + if (column < 0) { + column = index.column(); + } + return item->counterpart() ? this->index(item->counterpart(), column) : QModelIndex(); } int FileSystemItemModel::rowCount(const QModelIndex &parent) const { - if (const FileSystemItem *parentItem = (parent.isValid() ? reinterpret_cast(parent.internalPointer()) : m_rootItem)) { + if (const auto *const parentItem = (parent.isValid() ? reinterpret_cast(parent.internalPointer()) : m_rootItem)) { return parentItem->children().size(); } else { return 0; @@ -236,7 +240,7 @@ int FileSystemItemModel::rowCount(const QModelIndex &parent) const bool FileSystemItemModel::hasChildren(const QModelIndex &parent) const { - if (const FileSystemItem *parentItem = (parent.isValid() ? reinterpret_cast(parent.internalPointer()) : m_rootItem)) { + if (const auto *const parentItem = (parent.isValid() ? reinterpret_cast(parent.internalPointer()) : m_rootItem)) { return parentItem->children().size() > 0; } else { return false; diff --git a/renamingutility/filesystemitemmodel.h b/renamingutility/filesystemitemmodel.h index d0690d4..0606165 100644 --- a/renamingutility/filesystemitemmodel.h +++ b/renamingutility/filesystemitemmodel.h @@ -14,9 +14,10 @@ class FileSystemItemModel : public QAbstractItemModel { public: explicit FileSystemItemModel(FileSystemItem *rootItem, QObject *parent = nullptr); - ~FileSystemItemModel(); void setRootItem(FileSystemItem *rootItem); + FileSystemItem *fileSystemItemFromIndex(const QModelIndex &index); + const FileSystemItem *fileSystemItemFromIndex(const QModelIndex &index) const; QVariant data(const QModelIndex &index, int role) const; bool setData(const QModelIndex &index, const QVariant &value, int role); QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; diff --git a/renamingutility/filteredfilesystemitemmodel.cpp b/renamingutility/filteredfilesystemitemmodel.cpp index 312f8cc..681cd1d 100644 --- a/renamingutility/filteredfilesystemitemmodel.cpp +++ b/renamingutility/filteredfilesystemitemmodel.cpp @@ -15,23 +15,28 @@ FilteredFileSystemItemModel::FilteredFileSystemItemModel(ItemStatus statusFilter bool FilteredFileSystemItemModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { - QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent); - if (sourceIndex.isValid()) { - if (FileSystemItem *item = reinterpret_cast(sourceIndex.internalPointer())) { - if (item->status() == m_statusFilter) { - return true; - } else if (item->status() == ItemStatus::Current && !item->counterpart() && !item->note().isEmpty()) { - return true; - } else if (item->type() == ItemType::Dir) { - QModelIndex child = sourceIndex.child(0, 0); - while (child.isValid()) { - if (filterAcceptsRow(child.row(), sourceIndex)) { - return true; - } - child = sourceIndex.child(child.row() + 1, 0); - } - } + const auto sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent); + if (!sourceIndex.isValid()) { + return false; + } + const auto *const item = reinterpret_cast(sourceIndex.internalPointer()); + if (!item) { + return false; + } + + if (item->status() == m_statusFilter || (item->status() == ItemStatus::Current && !item->counterpart() && !item->note().isEmpty())) { + return true; + } + if (item->type() != ItemType::Dir) { + return false; + } + + auto child = sourceIndex.child(0, 0); + while (child.isValid()) { + if (filterAcceptsRow(child.row(), sourceIndex)) { + return true; } + child = sourceIndex.child(child.row() + 1, 0); } return false; } @@ -43,9 +48,8 @@ bool FilteredFileSystemItemModel::filterAcceptsColumn(int sourceColumn, const QM return sourceColumn == 0; case ItemStatus::New: return sourceColumn == 1 || sourceColumn == 2; - default: - return false; } + return false; } } // namespace RenamingUtility diff --git a/renamingutility/renamingengine.cpp b/renamingutility/renamingengine.cpp index ba39ad3..17469f7 100644 --- a/renamingutility/renamingengine.cpp +++ b/renamingutility/renamingengine.cpp @@ -204,7 +204,7 @@ unique_ptr RenamingEngine::generatePreview(const QDir &dir, File void RenamingEngine::applyChangings(FileSystemItem *parentItem) { - for (FileSystemItem *item : parentItem->children()) { + for (auto *const item : parentItem->children()) { if (!item->applied() && !item->errorOccured()) { switch (item->status()) { case ItemStatus::New: { @@ -277,7 +277,7 @@ void RenamingEngine::applyChangings(FileSystemItem *parentItem) void RenamingEngine::setError(const QList items) { - for (FileSystemItem *item : items) { + for (auto *const item : items) { item->setErrorOccured(true); item->setNote(tr("skipped due to error of superior item")); } diff --git a/renamingutility/tageditorobject.cpp b/renamingutility/tageditorobject.cpp index 0293b71..83802dd 100644 --- a/renamingutility/tageditorobject.cpp +++ b/renamingutility/tageditorobject.cpp @@ -228,30 +228,29 @@ TAGEDITOR_JS_VALUE TagEditorObject::parseFileName(const QString &fileName) TAGEDITOR_JS_VALUE TagEditorObject::allFiles(const QString &dirName) { const QDir dir(dirName); - if (dir.exists()) { - const auto files(dir.entryList(QDir::Files)); - auto entriesObj = m_engine->newArray(static_cast(files.size())); - quint32 counter = 0; - for (const auto &file : files) { - entriesObj.setProperty(counter, file TAGEDITOR_JS_READONLY); - ++counter; - } - return entriesObj; - } else { + if (!dir.exists()) { return TAGEDITOR_JS_VALUE(); } + const auto files(dir.entryList(QDir::Files)); + auto entriesObj = m_engine->newArray(static_cast(files.size())); + quint32 counter = 0; + for (const auto &file : files) { + entriesObj.setProperty(counter++, file TAGEDITOR_JS_READONLY); + } + return entriesObj; } TAGEDITOR_JS_VALUE TagEditorObject::firstFile(const QString &dirName) { const QDir dir(dirName); - if (dir.exists()) { - const auto files(dir.entryList(QDir::Files)); - if (!files.empty()) { - return TAGEDITOR_JS_VALUE(files.first()); - } + if (!dir.exists()) { + return TAGEDITOR_JS_VALUE(); } - return TAGEDITOR_JS_VALUE(); + const auto files(dir.entryList(QDir::Files)); + if (files.empty()) { + return TAGEDITOR_JS_VALUE(); + } + return TAGEDITOR_JS_VALUE(files.first()); } void TagEditorObject::writeLog(const QString &message) diff --git a/resources/scripts/renamefiles/example1.js b/resources/scripts/renamefiles/example1.js index f089bf5..8c16c23 100644 --- a/resources/scripts/renamefiles/example1.js +++ b/resources/scripts/renamefiles/example1.js @@ -2,49 +2,47 @@ // This is an example script demonstrating how the renaming tool can be used. // +// // script configuration +// // specifies the separator between artist, album and track number var separator = ", "; // specifies the separator between title and other fields var lastSeparator = " - "; // specifies whether the artist name should be included -var includeArtist = false; +var includeArtist = true; // specifies whether the album name should be included -var includeAlbum = false; +var includeAlbum = true; // specifies whether the title should be included var includeTitle = true; -// specifies the distribution directory -// all files will be moved in an appropriate subdirectory in the -// distribution directory if one is specified -var distDir = false; -// string used for "miscellaneous" category -var misc = "misc"; -// directory used to store collections +// specifies the "distribution directory" +//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"; +// directory used to store miscellaneous songs by miscellaneous artists +var miscDir = "misc"; +// directory used for miscellaneous songs by specific artist +var miscAlbumDir = "misc"; +// condition to move files to miscDir +var isMiscFile = function (tag) { return tag.comment === "misc"; }; +// condition to consider files part of a collection which contains songs from multiple artists +var isPartOfCollection = function (tag) { return tag.comment === "collection"; } -// define some helper functions +// +// helper functions +// -/*! - * Returns whether the specified \a value is not undefined - * and not an empty string. - */ +// returns whether the specified \a value is not undefined and not an empty string. function notEmpty(value) { return value !== undefined && value !== ""; } - -/*! - * Returns whether the specified \a value is not undefined - * and not zero. - */ +// returns whether the specified \a value is not undefined and not zero. function notNull(value) { return value !== undefined && value !== 0; } - -/*! - * Returns the string representation of \a pos using at least as - * many digits as \a total has. - */ +// returns the string representation of \a pos using at least as many digits as \a total has function appropriateDigitCount(pos, total) { var res = pos + ""; var count = (total + "").length; @@ -53,152 +51,147 @@ function appropriateDigitCount(pos, total) { } return res; } - -/*! - * Returns a copy of the specified \a name with characters that might be - * avoided in file names striped out. - */ +// returns a copy of the specified \a name with characters that might be avoided in file names striped out function validFileName(name) { - if(name !== undefined) { - return name.replace(/[\/\\]/gi, " - ").replace(/[<>?!*|:\"\n\f\r]/gi, ""); - } else { - return ""; - } + return name !== undefined ? name.replace(/[\/\\]/gi, " - ").replace(/[<>?!*|:\"\n\f\r]/gi, "") : ""; } - -/*! - * Returns a copy of the specified \a name with characters that might be - * avoided in directory names striped out. - */ +// returns a copy of the specified \a name with characters that might be avoided in directory names striped out. function validDirectoryName(name) { - if(name !== undefined) { - return name.replace(/[\/\\]/gi, " - ").replace(/[<>?!*|:\".\n\f\r]/gi, ""); - } else { - return ""; - } + return name !== undefined ? name.replace(/[\/\\]/gi, " - ").replace(/[<>?!*|:\".\n\f\r]/gi, "") : ""; } -// the actual script +// +// actual script +// -// check whether we have to deal with a file or a directory -if(tageditor.isFile) { - // parse file using the built-in parseFileInfo function - var fileInfo = tageditor.parseFileInfo(tageditor.currentPath); - var tag = fileInfo.tag; // get the tag information - // read title and track number from the file name using the built-in parseFileName function - var infoFromFileName = tageditor.parseFileName(fileInfo.currentBaseName); - // read the suffix from the file info object to filter backup and temporary files - if(fileInfo.currentName === "desktop.ini") { - tageditor.skip(); // skip these files - } else if(fileInfo.currentSuffix === "bak") { - // filter backup by putting them in a separate directory - tageditor.move("backups"); - } else if(fileInfo.currentSuffix === "tmp") { - // filter temporary files in the same way as backup files - tageditor.move("temp"); - } else { - // define an array for the fields; will be joined later - var fields = []; - // get the artist and remove invalid characters - var artist = validFileName(tag.artist); - // add artist to the fields array - // (if configured and present and if it is no collection) - if(includeArtist && tag.comment !== "collection") { - if(notEmpty(artist)) { - fields.push(artist); - } - } - // get the album and remove invalid characters - var album = validFileName(tag.album); - // add album to the fields array (if configure and present) - if(includeAlbum) { - if(notEmpty(tag.album)) { - fields.push(album); - } - } - // get the track/disk position; use the value from the tag if possible - if(notNull(tag.trackPos)) { - // define an array for the track position; will be joined later - var pos = []; - // push the disk position - if(notNull(tag.diskPos) - && notNull(tag.diskTotal) - && tag.diskTotal >= 2) { - pos.push(appropriateDigitCount(tag.diskPos, tag.diskTotal)); - } - // push the track count - if(notNull(tag.trackTotal)) { - pos.push(appropriateDigitCount(tag.trackPos, tag.trackTotal)); - } else { - pos.push(appropriateDigitCount(tag.trackPos, 10)); - } - fields.push(pos.join("-")); - } else if(notNull(infoFromFileName.trackPos)) { - // get the track position from the file name if the tag has no track position field - fields.push(appropriateDigitCount(infoFromFileName.trackPos, 10)); - } - // join the first part of the new name - var newName = fields.join(separator); - // get the title - var title = validFileName(tag.title); - // append the title (if configured and present) - if(includeTitle) { - // use value from file name if the tag has no title information - if(!notEmpty(title)) { - title = validFileName(infoFromFileName.title); - } - if(newName.length > 0) { - newName = newName.concat(lastSeparator, title); - } else { - newName = newName.concat(title); - } - } - // get an appropriate suffix - var suffix = ""; - if(notEmpty(fileInfo.suitableSuffix)) { - // get a suitable suffix from the file info object if available - suffix = fileInfo.suitableSuffix; - } else if(notEmpty(fileInfo.currentSuffix)) { - // or just use the current suffix otherwise - suffix = fileInfo.currentSuffix; - } - // append the suffix - if(notEmpty(suffix)) { - newName = newName.concat(".", suffix); - } - // apply new name - tageditor.rename(newName); - // set the distribution directory - if(distDir) { - var path = [distDir]; - var artist = validDirectoryName(tag.artist); - if(tag.comment === "collection") { - path.push(collectionsDir); - } else { - if(notEmpty(artist)) { - path.push(artist); - } else { - path.push(misc); - } - } - var album = validDirectoryName(tag.album); - if(notEmpty(album)) { - if(notEmpty(tag.year)) { - path.push([tag.year.split("-")[0], album].join(" - ")); - } else { - path.push(album); - } - } else if(notEmpty(artist)) { - path.push(misc); - } - if(tag.diskTotal >= 2) { - path.push("Disk " + appropriateDigitCount(tag.diskPos, tag.diskTotal)); - } - // apply new relative directory - tageditor.move(path.join("/")); - } - } -} else if(tageditor.isDir) { - // skip directories in this example script +// skip directories in this example script +if (!tageditor.isFile) { tageditor.skip(); + return; } + +// parse file using the built-in parseFileInfo function +var fileInfo = tageditor.parseFileInfo(tageditor.currentPath); +var tag = fileInfo.tag; + +// deduce title and track number from the file name using the built-in parseFileName function (as fallback if tags missing) +var infoFromFileName = tageditor.parseFileName(fileInfo.currentBaseName); + +// skip hidden and "desktop.ini" files +if (fileInfo.currentName.indexOf(".") === 0 || fileInfo.currentName === "desktop.ini") { + tageditor.skip(); + return; +} +// skip files which don't contain audio or video tracks +if (!fileInfo.hasAudioTracks && !fileInfo.hasVideoTracks) { + tageditor.skip(); + return; +} + +// filter backup and temporary files by putting them in a separate directory +if (fileInfo.currentSuffix === "bak") { + tageditor.move("backups"); + return; +} +if (fileInfo.currentSuffix === "tmp") { + tageditor.move("temp"); + return; +} + +// define an array for the fields to be joined later +var fields = []; + +// get the artist, remove invalid characters and add it to fields array +var artist = validFileName(tag.artist); +if (includeArtist && !isPartOfCollection(tag) && notEmpty(artist)) { + fields.push(artist); +} + +// get the album and remove invalid characters and add it to fields array +var album = validFileName(tag.album); +if (includeAlbum && notEmpty(tag.album)) { + fields.push(album); +} + +// get the track/disk position and add it to fields array +// use the value from the tag if possible; otherwise the value deduced from the filename +if (notNull(tag.trackPos)) { + var pos = []; + // push the disk position + if (notNull(tag.diskPos) && notNull(tag.diskTotal) && tag.diskTotal >= 2) { + pos.push(appropriateDigitCount(tag.diskPos, tag.diskTotal)); + } + // push the track count + if (notNull(tag.trackTotal)) { + pos.push(appropriateDigitCount(tag.trackPos, tag.trackTotal)); + } else { + pos.push(appropriateDigitCount(tag.trackPos, 10)); + } + fields.push(pos.join("-")); +} else if (notNull(infoFromFileName.trackPos)) { + fields.push(appropriateDigitCount(infoFromFileName.trackPos, 10)); +} + +// join the first part of the new name +var newName = fields.join(separator); + +// get the title and append it +var title = validFileName(tag.title); +if (includeTitle) { + // use value from file name if the tag has no title information + if (!notEmpty(title)) { + title = validFileName(infoFromFileName.title); + } + if (newName.length > 0) { + newName = newName.concat(lastSeparator, title); + } else { + newName = newName.concat(title); + } +} + +// append an appropriate suffix +var suffix = ""; +if (notEmpty(fileInfo.suitableSuffix)) { + // get a suitable suffix from the file info object if available + suffix = fileInfo.suitableSuffix; +} else if (notEmpty(fileInfo.currentSuffix)) { + // or just use the current suffix otherwise + suffix = fileInfo.currentSuffix; +} +if (notEmpty(suffix)) { + newName = newName.concat(".", suffix); +} + +// apply new name +tageditor.rename(newName); + +// set the distribution directory +if (!distDir) { + return; +} +var path = [distDir]; +var artist = validDirectoryName(tag.artist); +if (isPartOfCollection(tag)) { + path.push(collectionsDir); +} else if (isMiscFile(tag)) { + path.push(miscDir); +} else if (notEmpty(artist)) { + path.push(artist); +} else { + path.push(misc); +} +var album = validDirectoryName(tag.album); +if (notEmpty(album)) { + if (notEmpty(tag.year)) { + path.push([tag.year.split("-")[0], album].join(" - ")); + } else { + path.push(album); + } +} else if (notEmpty(artist) && !isMiscFile(tag)) { + path.push(miscAlbumDir); +} +if (tag.diskTotal >= 2) { + path.push("Disk " + appropriateDigitCount(tag.diskPos, tag.diskTotal)); +} +// apply new relative directory +tageditor.move(path.join("/"));