Skip to content

Commit

Permalink
tidy sql database, library and player
Browse files Browse the repository at this point in the history
  • Loading branch information
Gibbz committed Jul 25, 2020
1 parent 6b61736 commit f0d41fa
Show file tree
Hide file tree
Showing 17 changed files with 285 additions and 311 deletions.
2 changes: 0 additions & 2 deletions audiobook.pro
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ HEADERS += \
src/chapter.h \
src/chaptermodel.h \
src/database.h \
src/library.h \
src/libraryfilterproxy.h \
src/librarymodel.h \
src/player.h \
Expand Down Expand Up @@ -191,7 +190,6 @@ HEADERS += \
SOURCES += \
src/chaptermodel.cpp \
src/database.cpp \
src/library.cpp \
src/libraryfilterproxy.cpp \
src/librarymodel.cpp \
src/main.cpp \
Expand Down
19 changes: 19 additions & 0 deletions src/book.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <QString>
#include <QVector>
#include <QFileInfo>
#include "chapter.h"

class Book
Expand Down Expand Up @@ -31,6 +32,24 @@ class Book
duration += xChapter.duration;
chapters.append(xChapter);
}

void ready() {
if (!isEmpty()) {
if (chapters.size() == 1) {
title = chapters[0].title;
} else {
if (chapters[0].title == chapters[1].title)
title = chapters[0].title;
}

artist = chapters[0].artist;
genre = chapters[0].genre;
year = chapters[0].year;
}

if (title.isEmpty())
title = QFileInfo(path).baseName().replace("_", " ");
}
};

#endif // BOOK_H
2 changes: 2 additions & 0 deletions src/chapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ class Chapter
QString title;
qint64 duration = -1;

bool isEmpty() { return duration == -1; };

bool operator==(const Chapter& rhs) {
if (path == rhs.path)
return true;
Expand Down
7 changes: 3 additions & 4 deletions src/chaptermodel.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include <QDebug>
#include "chaptermodel.h"
#include "player.h"
#include "library.h"
#include "util.h"


Expand All @@ -26,7 +25,7 @@ void ChapterModel::chapterIndexChanged(int xIndex)

int ChapterModel::rowCount(const QModelIndex & /*parent*/) const
{
const Book *book = Library::instance()->getCurrentItem();
Book * book = Player::instance()->getCurrentItem();
if (book == nullptr)
return 0;
return book->chapters.size();
Expand All @@ -35,10 +34,10 @@ int ChapterModel::rowCount(const QModelIndex & /*parent*/) const

QVariant ChapterModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || Library::instance()->isEmpty())
if (!index.isValid())
return QVariant();

const Book *book = Library::instance()->getCurrentItem();
const Book *book = Player::instance()->getCurrentItem();
if (book == nullptr)
return QVariant();

Expand Down
156 changes: 150 additions & 6 deletions src/database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>
#include "library.h"
#include "database.h"
#include "util.h"
#include "settings.h"


Database::Database(QObject *parent)
: QObject(parent)
{
// Library path from settings
mLibraryPath = Settings::value("library_path", Util::getMusicLocation()).toString();

QString database_path = Util::getAppConfigLocation() + "/library.db";
QString database_name("Library");
qDebug() << database_path;
Expand All @@ -27,6 +30,10 @@ Database::Database(QObject *parent)

// create db or load
initDatabase();

// nothing in library, rescan
if (isEmpty())
updateLibrary();
}

Database *Database::instance()
Expand All @@ -49,6 +56,37 @@ Database::~Database()
}


QStringList Database::getBookDirs()
{
QStringList result;

// loop dirs
QDir lib_dir(mLibraryPath);
QDirIterator directories(mLibraryPath, QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);

while(directories.hasNext()) {
directories.next();

// does folder contain any audio files? if we have audio files, this is a book
QDir current_dir(directories.filePath());
QStringList dir_list = current_dir.entryList(mFileFilters, QDir::NoDotAndDotDot | QDir::Files);
if (dir_list.count() == 0)
continue;

result.append(directories.filePath().replace(mLibraryPath, ""));
}

return result;
}


QStringList Database::getBookFiles(const QString &xPath)
{
QDir current_dir(xPath);
return current_dir.entryList(mFileFilters, QDir::NoDotAndDotDot | QDir::Files);
}


void Database::initDatabase()
{
QStringList tables = mDatabase.tables();
Expand Down Expand Up @@ -121,7 +159,7 @@ QVariant Database::getInfo(const QString &xKey)



void Database::setChapter(const Chapter &xChapter)
void Database::writeChapter(const Chapter &xChapter)
{
QSqlQuery query(mDatabase);
query.prepare("REPLACE INTO files (path, title, duration, artist, genre, year) VALUES (?, ?, ?, ?, ?, ?)");
Expand All @@ -136,7 +174,7 @@ void Database::setChapter(const Chapter &xChapter)
}
}

const Chapter Database::getChapter(const QString &xPath)
Chapter Database::getChapter(const QString &xPath)
{
Chapter c;
c.path = xPath;
Expand All @@ -146,6 +184,7 @@ const Chapter Database::getChapter(const QString &xPath)
query.addBindValue(xPath);

if (query.exec()) {
// from db
while (query.next()) { // get first result
c.title = query.value("title").toString();
c.duration = query.value("duration").toInt();
Expand All @@ -155,11 +194,31 @@ const Chapter Database::getChapter(const QString &xPath)
}
}

if (c.isEmpty()) {
// from file
QString abs_path = mLibraryPath + xPath;
QFileInfo file_info = QFileInfo(abs_path);

c.duration = Util::getTimeMSec(abs_path);
c.artist = Util::getTagArtist(abs_path);
c.genre = Util::getTagGenre(abs_path);
c.title = Util::getTagTitle(abs_path);
c.year = Util::getTagYear(abs_path);

if (c.title.isEmpty())
c.title = Util::toCamelCase(file_info.baseName().replace("_", " "));

if (c.year == -1)
c.year = file_info.birthTime().date().year();

writeChapter(c);
}

return c;
}


void Database::setBook(const Book &xBook)
void Database::writeBook(const Book &xBook)
{
QSqlQuery query(mDatabase);
query.prepare("REPLACE INTO books (path, progress) VALUES (?, ?)");
Expand All @@ -171,18 +230,19 @@ void Database::setBook(const Book &xBook)
}


const Book Database::getBook(const QString &xPath)
Book Database::getBook(const QString &xPath)
{
Book b;
b.path = xPath;

QSqlQuery query(mDatabase);

// get books
// get book info
query.prepare("SELECT * FROM books WHERE path = ?");
query.addBindValue(xPath);

if (query.exec()) {
// from db
while (query.next()) { // get first result
b.progress = query.value("progress").toInt();
}
Expand All @@ -206,8 +266,92 @@ const Book Database::getBook(const QString &xPath)
}
}

if (b.isEmpty()) {
// from file
QStringList chapter_files = getBookFiles(mLibraryPath + xPath);

for (QString current_file : chapter_files) {
QString chapter_path = xPath + "/" + current_file;
Chapter c = getChapter(chapter_path);
b.addChapter(c);
}

writeBook(b);
}

b.ready();
return b;
}



QString Database::libraryPath() const
{
return mLibraryPath;
}


void Database::setLibraryPath(QString &xPath) {
xPath = xPath.replace("file://","");
if (xPath == mLibraryPath)
return;
mLibraryPath = xPath;
Settings::setValue("library_path", mLibraryPath);
qDebug() << mLibraryPath;
updateLibrary();
emit pathChanged();
}


int Database::size() const
{
return mLibraryItems.size();
}


bool Database::isEmpty() const
{
return mLibraryItems.isEmpty();
}


QVector<Book> Database::getLibraryItems() {
return mLibraryItems;
}


Book * Database::getLibraryItem(QString &xPath)
{
for(Book &b: mLibraryItems) {
if (b.path == xPath)
return &b;
}
return nullptr;
}


bool caseInsensitiveLessThan(const Book &s1, const Book &s2) {
return s1.title.toLower() < s2.title.toLower();
}


void Database::updateLibrary() {
// delete old books
mLibraryItems = QVector<Book>();

// set library path
setInfo("library_path", mLibraryPath);

// get book directories
QStringList book_dirs = getBookDirs();
for (QString book_path : book_dirs) {
Book book = getBook(book_path);
mLibraryItems.append(book);
}

// sort
qSort(mLibraryItems.begin(), mLibraryItems.end(), caseInsensitiveLessThan);

emit libraryUpdated();
}

36 changes: 29 additions & 7 deletions src/database.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,29 +13,51 @@ class Database : public QObject
Q_OBJECT
const static int DB_VERSION = 0;

Q_PROPERTY(QString libraryPath READ libraryPath WRITE setLibraryPath NOTIFY pathChanged)
Q_PROPERTY(int size READ size)

public:
Database(const Database&) = delete; // disable copy for singleton
static Database *instance();
static QObject *qmlInstance(QQmlEngine *engine, QJSEngine *scriptEngine);
~Database() override;

void initDatabase();
// from file
QStringList getBookDirs();
QStringList getBookFiles(const QString &xPath);

// database
void initDatabase();
void setInfo(const QString &xKey, const QString &xValue);

QVariant getInfo(const QString &xKey);
void setChapter(const Chapter &xChapter);
const Chapter getChapter(const QString &xPath);
void writeChapter(const Chapter &xChapter);
Chapter getChapter(const QString &xPath);
void writeBook(const Book &xBook);
Book getBook(const QString &xPath);

void setBook(const Book &xBook);
const Book getBook(const QString &xPath);

// library
QString libraryPath() const;
void setLibraryPath(QString &xPath);
int size() const;
bool isEmpty() const;
QVector<Book> getLibraryItems();
Book * getLibraryItem(QString &xPath);

signals:
void pathChanged();
void libraryUpdated();
void currentItemChanged();

public slots:
void updateLibrary();

private:
explicit Database(QObject *parent = nullptr);

QVector<Book> mLibraryItems;
QString mLibraryPath;
QSqlDatabase mDatabase;
QStringList mFileFilters = { "*.mp3", "*.ogg", "*.wav" };

};

Expand Down
Loading

0 comments on commit f0d41fa

Please sign in to comment.