Implemented directory scanning and adding tracks to library
authorNikolay Tischenko <niktischenko@gmail.com>
Sun, 5 Sep 2010 13:40:48 +0000 (20:40 +0700)
committerNikolay Tischenko <niktischenko@gmail.com>
Sun, 5 Sep 2010 13:40:48 +0000 (20:40 +0700)
14 files changed:
someplayer.pro
someplayer.pro.user
src/dbstorage.cpp
src/library.cpp
src/library.h
src/main.cpp
src/mainwindow.cpp
src/mainwindow.h
src/mediascanner.cpp [new file with mode: 0644]
src/mediascanner.h [new file with mode: 0644]
src/someplayer.h
src/tagresolver.cpp [new file with mode: 0644]
src/tagresolver.h [new file with mode: 0644]
src/trackmetainformation.cpp

index 09682c6..d6ad5bc 100644 (file)
@@ -19,7 +19,9 @@ SOURCES += src/main.cpp\
     src/library.cpp \
     src/storage.cpp \
     src/filestorage.cpp \
     src/library.cpp \
     src/storage.cpp \
     src/filestorage.cpp \
-    src/dbstorage.cpp
+    src/dbstorage.cpp \
+    src/mediascanner.cpp \
+    src/tagresolver.cpp
 
 HEADERS  += src/mainwindow.h \
         src/player.h \
 
 HEADERS  += src/mainwindow.h \
         src/player.h \
@@ -30,7 +32,9 @@ HEADERS  += src/mainwindow.h \
     src/library.h \
     src/storage.h \
     src/filestorage.h \
     src/library.h \
     src/storage.h \
     src/filestorage.h \
-    src/dbstorage.h
+    src/dbstorage.h \
+    src/mediascanner.h \
+    src/tagresolver.h
 
 FORMS    += src/ui/mainwindow.ui
 
 
 FORMS    += src/ui/mainwindow.ui
 
index 5ed6616..4082206 100644 (file)
   <valuemap type="QVariantMap">
    <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString">Maemo</value>
    <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.Target.MaemoDeviceTarget</value>
   <valuemap type="QVariantMap">
    <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString">Maemo</value>
    <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.Target.MaemoDeviceTarget</value>
-   <value key="ProjectExplorer.Target.ActiveBuildConfiguration" type="int">1</value>
+   <value key="ProjectExplorer.Target.ActiveBuildConfiguration" type="int">0</value>
    <value key="ProjectExplorer.Target.ActiveRunConfiguration" type="int">0</value>
    <valuemap key="ProjectExplorer.Target.BuildConfiguration.0" type="QVariantMap">
     <valuemap key="ProjectExplorer.BuildConfiguration.BuildStep.0" type="QVariantMap">
    <value key="ProjectExplorer.Target.ActiveRunConfiguration" type="int">0</value>
    <valuemap key="ProjectExplorer.Target.BuildConfiguration.0" type="QVariantMap">
     <valuemap key="ProjectExplorer.BuildConfiguration.BuildStep.0" type="QVariantMap">
     <valuemap key="Qt4ProjectManager.MaemoRunConfiguration.DebuggingHelpersLastDeployed" type="QVariantMap"/>
     <value key="Qt4ProjectManager.MaemoRunConfiguration.DeviceId" type="qulonglong">1</value>
     <valuemap key="Qt4ProjectManager.MaemoRunConfiguration.LastDeployed" type="QVariantMap">
     <valuemap key="Qt4ProjectManager.MaemoRunConfiguration.DebuggingHelpersLastDeployed" type="QVariantMap"/>
     <value key="Qt4ProjectManager.MaemoRunConfiguration.DeviceId" type="qulonglong">1</value>
     <valuemap key="Qt4ProjectManager.MaemoRunConfiguration.LastDeployed" type="QVariantMap">
-     <value key="192.168.77.2" type="QDateTime">2010-09-05T03:10:24</value>
+     <value key="192.168.77.2" type="QDateTime">2010-09-05T16:54:31</value>
     </valuemap>
    </valuemap>
    <value key="ProjectExplorer.Target.RunConfigurationCount" type="int">1</value>
     </valuemap>
    </valuemap>
    <value key="ProjectExplorer.Target.RunConfigurationCount" type="int">1</value>
index 95cc980..7c6af3a 100644 (file)
@@ -270,7 +270,14 @@ void DbStorage::addTrack(Track track) {
                //big bang
                return;
        }
                //big bang
                return;
        }
-       QSqlQuery* query = _insert_track_query;
+       QSqlQuery *query = _check_track_query;
+       query->bindValue(":source", source);
+       query->exec();
+       if (query->next()) {
+               // already in datebase, skip
+               return;
+       }
+       query = _insert_track_query;
        query->bindValue(":title", title);
        query->bindValue(":artist_id", artist_id);
        query->bindValue(":album_id", album_id);
        query->bindValue(":title", title);
        query->bindValue(":artist_id", artist_id);
        query->bindValue(":album_id", album_id);
index bfd8a1d..5dcfaf4 100644 (file)
@@ -3,9 +3,17 @@
 using namespace SomePlayer::DataObjects;
 using namespace SomePlayer::Storage;
 
 using namespace SomePlayer::DataObjects;
 using namespace SomePlayer::Storage;
 
-Library::Library(QString databasePath, QString playlistsPath) {
+#include "mediascanner.h"
+#include <QDir>
+#include <QDebug>
+
+Library::Library(QString databasePath, QString playlistsPath) : QObject(0) {
        _library_storage = new DbStorage(databasePath);
        _playlist_storage = new FileStorage(playlistsPath);
        _library_storage = new DbStorage(databasePath);
        _playlist_storage = new FileStorage(playlistsPath);
+       _scanner = new MediaScanner();
+       _resolver = new TagResolver(this);
+       connect(_scanner, SIGNAL(scanFinish(QStringList)), _resolver, SLOT(decode(QStringList)));
+       connect(_resolver, SIGNAL(decoded(Track)), this, SLOT(addTrack(Track)));
 }
 
 Library::~Library() {
 }
 
 Library::~Library() {
@@ -14,7 +22,8 @@ Library::~Library() {
 }
 
 void Library::addDirectory(QString path) {
 }
 
 void Library::addDirectory(QString path) {
-       /// TODO: implement this
+       _scanner->init(path);
+       _scanner->start(QThread::LowestPriority);
 }
 
 void Library::addFile(QString path) {
 }
 
 void Library::addFile(QString path) {
@@ -57,6 +66,10 @@ void Library::removeTrack(Track track) {
        _library_storage->removeTrack(track);
 }
 
        _library_storage->removeTrack(track);
 }
 
+void Library::addTrack(Track track) {
+       _library_storage->addTrack(track);
+}
+
 void Library::addToFavorites(Track track) {
        _library_storage->addToFavorites(track);
 }
 void Library::addToFavorites(Track track) {
        _library_storage->addToFavorites(track);
 }
index 1a4ecc7..08414c3 100644 (file)
@@ -6,6 +6,8 @@
 #include "playlist.h"
 #include "dbstorage.h"
 #include "filestorage.h"
 #include "playlist.h"
 #include "dbstorage.h"
 #include "filestorage.h"
+#include "mediascanner.h"
+#include "tagresolver.h"
 
 // represents media library: tracks, playlists
 // it uses different media storages for tracks and playlists
 
 // represents media library: tracks, playlists
 // it uses different media storages for tracks and playlists
@@ -15,11 +17,13 @@ using SomePlayer::DataObjects::Track;
 using SomePlayer::DataObjects::Playlist;
 using SomePlayer::Storage::DbStorage;
 using SomePlayer::Storage::FileStorage;
 using SomePlayer::DataObjects::Playlist;
 using SomePlayer::Storage::DbStorage;
 using SomePlayer::Storage::FileStorage;
+using SomePlayer::Storage::MediaScanner;
 
 namespace SomePlayer {
        namespace DataObjects {
 
 
 namespace SomePlayer {
        namespace DataObjects {
 
-               class Library {
+               class Library : public QObject {
+                       Q_OBJECT
                public:
                        Library(QString databasePath, QString playlistsPath);
                        ~Library();
                public:
                        Library(QString databasePath, QString playlistsPath);
                        ~Library();
@@ -36,12 +40,6 @@ namespace SomePlayer {
                        Playlist getNeverPlayed();
                        Playlist getRecentlyAdded();
 
                        Playlist getNeverPlayed();
                        Playlist getRecentlyAdded();
 
-                       void removeTrack(Track);
-                       void addTrack(Track);
-                       void addToFavorites(Track);
-
-                       void updateTrack(Track);
-
                        QList<Playlist> getPlaylists();
                        void savePlaylist(Playlist playlist);
                        void removePlaylist(Playlist playlist);
                        QList<Playlist> getPlaylists();
                        void savePlaylist(Playlist playlist);
                        void removePlaylist(Playlist playlist);
@@ -52,6 +50,14 @@ namespace SomePlayer {
                private:
                        DbStorage *_library_storage;
                        FileStorage *_playlist_storage;
                private:
                        DbStorage *_library_storage;
                        FileStorage *_playlist_storage;
+                       MediaScanner *_scanner;
+                       TagResolver *_resolver;
+
+               public slots:
+                       void removeTrack(Track);
+                       void addTrack(Track);
+                       void addToFavorites(Track);
+                       void updateTrack(Track);
                };
 
        };
                };
 
        };
index 35ab0cb..b42524a 100644 (file)
@@ -7,6 +7,7 @@ int main(int argc, char *argv[])
        a.setApplicationName("someplayer");
        MainWindow w;
 
        a.setApplicationName("someplayer");
        MainWindow w;
 
+
 #if defined(Q_WS_S60)
        w.showMaximized();
 #else
 #if defined(Q_WS_S60)
        w.showMaximized();
 #else
index 67141bc..2c576f9 100644 (file)
@@ -2,7 +2,7 @@
 #include "ui_mainwindow.h"
 #include <QFileDialog>
 #include <QMessageBox>
 #include "ui_mainwindow.h"
 #include <QFileDialog>
 #include <QMessageBox>
-#include "player.h"
+#include <QFile>
 
 MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
 
 MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
@@ -10,7 +10,6 @@ MainWindow::MainWindow(QWidget *parent) :
 {
        ui->setupUi(this);
        connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(openMedia()));
 {
        ui->setupUi(this);
        connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(openMedia()));
-       player = new Player();
 }
 
 MainWindow::~MainWindow()
 }
 
 MainWindow::~MainWindow()
@@ -20,7 +19,4 @@ MainWindow::~MainWindow()
 
 void MainWindow::openMedia()
 {
 
 void MainWindow::openMedia()
 {
-       QString filename = QFileDialog::getOpenFileName(this, "Open media", "/home/user/");
-       player->playSong(filename);
-
 }
 }
index 1a9e1f4..6662fb8 100644 (file)
@@ -2,7 +2,6 @@
 #define MAINWINDOW_H
 
 #include <QMainWindow>
 #define MAINWINDOW_H
 
 #include <QMainWindow>
-#include "player.h"
 
 namespace Ui {
        class MainWindow;
 
 namespace Ui {
        class MainWindow;
@@ -18,7 +17,6 @@ public:
 
 private:
        Ui::MainWindow *ui;
 
 private:
        Ui::MainWindow *ui;
-       Player *player;
 
 public slots:
        void openMedia();
 
 public slots:
        void openMedia();
diff --git a/src/mediascanner.cpp b/src/mediascanner.cpp
new file mode 100644 (file)
index 0000000..000d35c
--- /dev/null
@@ -0,0 +1,44 @@
+#include "mediascanner.h"
+
+using namespace SomePlayer::Storage;
+
+#include <QMap>
+
+MediaScanner::MediaScanner(QObject *parent) :
+               QThread(parent), _stopped(false), _initialized(false)
+{
+       REGISTERED_FILE_EXTENSIONS << "mp3" << "flac" << "wma" << "acc";
+       _iterator = NULL;
+}
+
+void MediaScanner::run() {
+       if (!_initialized)
+               return;
+       _foundMedia.clear();
+       while(!_stopped && _iterator->hasNext()) {
+               QString entry(_iterator->next());
+               QFileInfo info(entry);
+               if (info.isReadable()) {
+                       QString suffix = info.suffix().toLower();
+                       if (REGISTERED_FILE_EXTENSIONS.contains(suffix)) {
+                               if (!_foundMedia.contains(info.absoluteFilePath()))
+                                       _foundMedia << info.absoluteFilePath();
+                       }
+               }
+       }
+       emit scanFinish(_foundMedia);
+       _stopped = true;
+}
+
+void MediaScanner::stop() {
+       _stopped = true;
+       _initialized = false;
+}
+
+void MediaScanner::init(QString dir) {
+       _stopped = false;
+       _initialized = true;
+       if (!_iterator)
+               delete _iterator;
+       _iterator = new QDirIterator(QDir(dir), QDirIterator::Subdirectories);
+}
diff --git a/src/mediascanner.h b/src/mediascanner.h
new file mode 100644 (file)
index 0000000..c350f3a
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef MEDIASCANNER_H
+#define MEDIASCANNER_H
+
+#include "someplayer.h"
+#include "track.h"
+#include <QThread>
+#include <QDir>
+#include <QDirIterator>
+
+namespace SomePlayer {
+       namespace Storage {
+
+               class MediaScanner : public QThread
+               {
+
+                       Q_OBJECT
+               public:
+                       explicit MediaScanner(QObject *parent = 0);
+                       void run();
+
+               signals:
+                       void scanFinish(QStringList);
+               public slots:
+                       void stop();
+                       void init(QString);
+               private:
+                       QDirIterator *_iterator;
+                       bool _stopped;
+                       bool _initialized;
+                       QStringList REGISTERED_FILE_EXTENSIONS;
+                       QStringList _foundMedia;
+               };
+
+       };
+};
+
+#endif // MEDIASCANNER_H
index 5fb43f6..f87ce07 100644 (file)
@@ -13,6 +13,7 @@ namespace SomePlayer {
 // common includes
 
 #include <QString>
 // common includes
 
 #include <QString>
+#include <QStringList>
 #include <QList>
 #include <QMap>
 #include <QUrl>
 #include <QList>
 #include <QMap>
 #include <QUrl>
diff --git a/src/tagresolver.cpp b/src/tagresolver.cpp
new file mode 100644 (file)
index 0000000..8be3b86
--- /dev/null
@@ -0,0 +1,37 @@
+#include "tagresolver.h"
+
+using namespace SomePlayer::DataObjects;
+
+TagResolver::TagResolver(QObject *parent) :
+    QObject(parent)
+{
+       _metaObject = new Phonon::MediaObject(this);
+       connect(_metaObject, SIGNAL(stateChanged(Phonon::State,Phonon::State)), this, SLOT(metaStateChanged(Phonon::State,Phonon::State)));
+}
+
+void TagResolver::decode(QStringList files) {
+       _sources.clear();
+       foreach (QString filename, files) {
+               _sources.append(Phonon::MediaSource(filename));
+       }
+       if (!_sources.isEmpty()) {
+               _metaObject->setCurrentSource(_sources.at(0));
+       }
+}
+
+void TagResolver::metaStateChanged(Phonon::State newState, Phonon::State /*oldState*/) {
+       if (newState == Phonon::StoppedState) {
+               Phonon::MediaSource source = _metaObject->currentSource();
+               if (source.type() != Phonon::MediaSource::Invalid) {
+                       QMap<QString, QString> meta = _metaObject->metaData();
+                       TrackMetadata metadata(meta.value("TITLE"), meta.value("ARTIST"), meta.value("ALBUM"));
+                       Track track(0, metadata, source.fileName());
+                       emit decoded(track);
+                       int index = _sources.indexOf(source)+1;
+                       if (index != _sources.size()) {
+                               Phonon::MediaSource newSource = _sources.at(index);
+                               _metaObject->setCurrentSource(newSource);
+                       }
+               }
+       }
+}
diff --git a/src/tagresolver.h b/src/tagresolver.h
new file mode 100644 (file)
index 0000000..1a0a405
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef TAGRESOLVER_H
+#define TAGRESOLVER_H
+
+#include <QObject>
+#include "someplayer.h"
+#include "track.h"
+#include <phonon/MediaObject>
+#include <phonon/MediaSource>
+
+using SomePlayer::DataObjects::Track;
+
+class TagResolver : public QObject
+{
+    Q_OBJECT
+public:
+    explicit TagResolver(QObject *parent = 0);
+public slots:
+       void decode (QStringList files);
+
+signals:
+       void decoded(Track);
+
+private slots:
+       void metaStateChanged(Phonon::State newState, Phonon::State /*oldState*/);
+private:
+       QStringList _files;
+       Phonon::MediaObject *_metaObject;
+       QList<Phonon::MediaSource> _sources;
+
+};
+
+#endif // TAGRESOLVER_H
index e88f7ae..0cf35f4 100644 (file)
@@ -5,10 +5,10 @@ using namespace SomePlayer::DataObjects;
 TrackMetadata::TrackMetadata() {
 }
 
 TrackMetadata::TrackMetadata() {
 }
 
-TrackMetadata::TrackMetadata(QString title = "", QString artist = "", QString album = "") {
-       _metadata["TITLE"] = title;
-       _metadata["ARTIST"] = artist;
-       _metadata["ALBUM"] = album;
+TrackMetadata::TrackMetadata(QString title = "Unknown title", QString artist = "Unknown artist", QString album = "Unknown album") {
+       _metadata["TITLE"] = title == "" ? "Unknown title" : title;
+       _metadata["ARTIST"] = artist == "" ? "Unknown artist" : artist;
+       _metadata["ALBUM"] = album == "" ? "Unknown album" : album;
 }
 
 TrackMetadata::TrackMetadata(const TrackMetadata &metadata) {
 }
 
 TrackMetadata::TrackMetadata(const TrackMetadata &metadata) {