Implemented playlist storage
authorNikolay Tischenko <niktischenko@gmail.com>
Sun, 5 Sep 2010 17:21:13 +0000 (00:21 +0700)
committerNikolay Tischenko <niktischenko@gmail.com>
Sun, 5 Sep 2010 17:21:13 +0000 (00:21 +0700)
added track length to model and database

18 files changed:
someplayer.pro
someplayer.pro.user
src/dbstorage.cpp
src/dbstorage.h
src/filestorage.cpp
src/filestorage.h
src/library.cpp
src/library.h
src/mainwindow.cpp
src/mediascanner.cpp
src/playlist.cpp
src/playlist.h
src/storage.cpp [deleted file]
src/storage.h
src/tagresolver.cpp
src/tagresolver.h
src/trackmetainformation.cpp
src/trackmetainformation.h

index d6ad5bc..3a3ad14 100644 (file)
@@ -17,7 +17,6 @@ SOURCES += src/main.cpp\
     src/trackmetainformation.cpp \
     src/playlist.cpp \
     src/library.cpp \
-    src/storage.cpp \
     src/filestorage.cpp \
     src/dbstorage.cpp \
     src/mediascanner.cpp \
index 4082206..2d3304b 100644 (file)
     <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-05T16:54:31</value>
+     <value key="192.168.77.2" type="QDateTime">2010-09-05T23:00:23</value>
     </valuemap>
    </valuemap>
    <value key="ProjectExplorer.Target.RunConfigurationCount" type="int">1</value>
index 7c6af3a..4921371 100644 (file)
@@ -25,34 +25,34 @@ void DbStorage::_prepare_queries() {
        _get_albums_for_artist_query->prepare("SELECT name FROM album WHERE artist_id in (SELECT id from artist WHERE name = :name);");
 
        _get_tracks_for_album_query = new QSqlQuery(db);
-       _get_tracks_for_album_query->prepare("SELECT id, title, source, count FROM tracks WHERE artist_id IN "
+       _get_tracks_for_album_query->prepare("SELECT id, title, source, count, length FROM tracks WHERE artist_id IN "
                                                                                 "(SELECT id FROM artist WHERE name = :artist_name) AND album_id IN "
                                                                                 "(SELECT id FROM album WHERE name =: album_name);");
 
        _get_favorites_query = new QSqlQuery(db);
-       _get_favorites_query->prepare("SELECT track_id as id, title, artist, album.name as album, source, count FROM "
-                                                                 "(SELECT tracks.id AS track_id, artist.name AS artist, title, count, source, tracks.album_id FROM "
+       _get_favorites_query->prepare("SELECT track_id as id, title, artist, album.name as album, source, count, length FROM "
+                                                                 "(SELECT tracks.id AS track_id, artist.name AS artist, title, count, source, tracks.album_id, length FROM "
                                                                  "tracks JOIN artist ON tracks.artist_id = artist.id) "
                                                                  "JOIN album ON album_id = album.id WHERE track_id IN "
                                                                  "(SELECT track_id FROM favorites);");
 
        _get_most_played_query = new QSqlQuery(db);
-       _get_most_played_query->prepare("SELECT track_id as id, title, artist, album.name as album, source, count FROM "
-                                                                       "(SELECT tracks.id AS track_id, artist.name AS artist, title, count, source, tracks.album_id FROM "
+       _get_most_played_query->prepare("SELECT track_id as id, title, artist, album.name as album, source, count, length FROM "
+                                                                       "(SELECT tracks.id AS track_id, artist.name AS artist, title, count, source, tracks.album_id, length FROM "
                                                                        "tracks JOIN artist ON tracks.artist_id = artist.id) "
                                                                        "JOIN album ON album_id = album.id ORDER BY count DESC "
                                                                        "LIMIT 0, :max");
 
        _get_never_played_query = new QSqlQuery(db);
-       _get_never_played_query->prepare("SELECT track_id as id, title, artist, album.name as album, source, count FROM "
-                                                                        "(SELECT tracks.id AS track_id, artist.name AS artist, title, count, source, tracks.album_id FROM "
+       _get_never_played_query->prepare("SELECT track_id as id, title, artist, album.name as album, source, count, length FROM "
+                                                                        "(SELECT tracks.id AS track_id, artist.name AS artist, title, count, source, tracks.album_id, length FROM "
                                                                         "tracks JOIN artist ON tracks.artist_id = artist.id) "
                                                                         "JOIN album ON album_id = album.id "
                                                                         "WHERE count = 0");
 
        _get_recently_added_query = new QSqlQuery(db);
-       _get_recently_added_query->prepare("SELECT track_id as id, title, artist, album.name as album, source, count FROM "
-                                                                          "(SELECT tracks.id AS track_id, artist.name AS artist, title, count, source, tracks.album_id FROM "
+       _get_recently_added_query->prepare("SELECT track_id as id, title, artist, album.name as album, source, count, length FROM "
+                                                                          "(SELECT tracks.id AS track_id, artist.name AS artist, title, count, source, tracks.album_id, length FROM "
                                                                           "tracks JOIN artist ON tracks.artist_id = artist.id) "
                                                                           "JOIN album ON album_id = album.id "
                                                                           "WHERE track_id IN "
@@ -73,7 +73,7 @@ void DbStorage::_prepare_queries() {
        _insert_album_query->prepare("INSERT INTO album (name, artist_id) values (:name, :artist_id)");
 
        _insert_track_query = new QSqlQuery(db);
-       _insert_track_query->prepare("INSERT INTO tracks (title, artist_id, album_id, source) values (:title, :artist_id, :album_id, :source)");
+       _insert_track_query->prepare("INSERT INTO tracks (title, artist_id, album_id, source, length) values (:title, :artist_id, :album_id, :source, :length)");
 
        _insert_date_query = new QSqlQuery(db);
        _insert_date_query->prepare("INSERT INTO adding_date (track_id, date) values (:track_id, strftime('%s', 'now'))");
@@ -95,6 +95,7 @@ void DbStorage::_create_database_structure() {
                                                                                "title text, "
                                                                                "source text, "
                                                                                "count integer default 0, "
+                                                                               "length integer default 0, "
                                                                                "foreign key(artist_id) references artist(id), "
                                                                                "foreign key(album_id) references album(id) "
                                                                                ");");
@@ -115,6 +116,13 @@ DbStorage::~DbStorage() {
        delete _get_never_played_query;
        delete _get_recently_added_query;
        delete _get_tracks_for_album_query;
+       delete _check_album_query;
+       delete _check_artist_query;
+       delete _check_track_query;
+       delete _insert_album_query;
+       delete _insert_artist_query;
+       delete _insert_date_query;
+       delete _insert_track_query;
        db.close();
 }
 
@@ -153,7 +161,8 @@ QList<Track> DbStorage::getTracksForAlbum(QString album, QString artist) {
                QString title = query->value(1).toString();
                QString source = query->value(2).toString();
                int count = query->value(3).toInt();
-               TrackMetadata meta (title, artist, album);
+               int length = query->value(4).toInt();
+               TrackMetadata meta (title, artist, album, length);
                Track track(id, meta, source);
                track.setCount(count);
                tracks.append(track);
@@ -173,7 +182,8 @@ Playlist DbStorage::getFavorites() {
                QString album = query->value(3).toString();
                QString source = query->value(4).toString();
                int count = query->value(5).toInt();
-               TrackMetadata meta(title, artist, album);
+               int length = query->value(6).toInt();
+               TrackMetadata meta(title, artist, album, length);
                Track track(id, meta, source);
                track.setCount(count);
                playlist.addTrack(track);
@@ -194,7 +204,8 @@ Playlist DbStorage::getMostPlayed() {
                QString album = query->value(3).toString();
                QString source = query->value(4).toString();
                int count = query->value(5).toInt();
-               TrackMetadata meta(title, artist, album);
+               int length = query->value(6).toInt();
+               TrackMetadata meta(title, artist, album, length);
                Track track(id, meta, source);
                track.setCount(count);
                playlist.addTrack(track);
@@ -215,7 +226,8 @@ Playlist DbStorage::getNeverPlayed() {
                QString album = query->value(3).toString();
                QString source = query->value(4).toString();
                int count = query->value(5).toInt();
-               TrackMetadata meta(title, artist, album);
+               int length = query->value(6).toInt();
+               TrackMetadata meta(title, artist, album, length);
                Track track(id, meta, source);
                track.setCount(count);
                playlist.addTrack(track);
@@ -236,7 +248,8 @@ Playlist DbStorage::getRecentlyAdded() {
                QString album = query->value(3).toString();
                QString source = query->value(4).toString();
                int count = query->value(5).toInt();
-               TrackMetadata meta(title, artist, album);
+               int length = query->value(6).toInt();
+               TrackMetadata meta(title, artist, album, length);
                Track track(id, meta, source);
                track.setCount(count);
                playlist.addTrack(track);
@@ -282,6 +295,7 @@ void DbStorage::addTrack(Track track) {
        query->bindValue(":artist_id", artist_id);
        query->bindValue(":album_id", album_id);
        query->bindValue(":source", source);
+       query->bindValue(":length", track.metadata().length());
        if (query->exec()) {
                //ok
                query = _check_track_query;
index 76041d6..7b771b0 100644 (file)
@@ -19,7 +19,7 @@ using SomePlayer::DataObjects::Track;
 namespace SomePlayer {
        namespace Storage {
 
-               class DbStorage : public Storage {
+               class DbStorage {
                public:
                        DbStorage(QString path);
                        ~DbStorage();
index 27df605..f383a1c 100644 (file)
@@ -1,9 +1,17 @@
 #include "filestorage.h"
+#include <QDir>
+#include <QDirIterator>
+#include <QFileInfo>
+#include <QTextStream>
+#include <QRegExp>
 
 using namespace SomePlayer::Storage;
+using namespace SomePlayer::DataObjects;
 
 FileStorage::FileStorage(QString path) {
        _path_prefix = path;
+       _meta_regexp.setPattern("#META \\[(\\d+)\\].*::(.+)::,::(.+)::,::(.+)::");
+       _path_regexp.setPattern("#PATH (.+)");
 }
 
 QList<Playlist> FileStorage::getPlaylists() {
@@ -11,19 +19,85 @@ QList<Playlist> FileStorage::getPlaylists() {
        return stub;
 }
 
+Playlist FileStorage::getPlaylist(QString name) {
+       QFile playlistFile (_path_prefix+"/"+name+_PLAYLIST_FILE_EXTENSION_);
+       Playlist playlist;
+       playlist.setName("Bad playlist");
+       if (playlistFile.exists()) {
+               playlist.setName(name);
+               QTextStream stream(&playlistFile);
+               QString buffer = stream.readLine();
+               int index = 0;
+               if (buffer.startsWith(_PLAYLIST_SIGNATURE_)) {
+                       while (!stream.atEnd()) {
+                               buffer = stream.readLine();
+                               if (_meta_regexp.indexIn(buffer) != -1) {
+                                       int seconds = _meta_regexp.cap(0).toInt();
+                                       QString artist = _meta_regexp.cap(1);
+                                       QString album = _meta_regexp.cap(2);
+                                       QString title = _meta_regexp.cap(3);
+                                       buffer = stream.readLine();
+                                       if (_path_regexp.indexIn(buffer) != -1) {
+                                               QString source = _path_regexp.cap(0);
+                                               TrackMetadata meta(title, artist, album, seconds);
+                                               Track track(index++, meta, source);
+                                               playlist.addTrack(track);
+                                       }
+                               }
+                       }
+               }
+       }
+       return playlist;
+}
+
+QStringList FileStorage::getPlaylistsNames() {
+       QDir directory(_path_prefix);
+       QDirIterator iterator(directory, QDirIterator::FollowSymlinks);
+       QStringList playlistNames;
+       while (iterator.hasNext()) {
+               QString entry = iterator.next();
+               QFileInfo info(entry);
+               QString suffix = info.suffix().toLower();
+               if (suffix == _PLAYLIST_FILE_EXTENSION_) {
+                       playlistNames.append(info.fileName());
+               }
+       }
+       return playlistNames;
+}
+
 void FileStorage::savePlaylist(Playlist playlist) {
+       QString filename = _path_prefix+playlist.name()+_PLAYLIST_FILE_EXTENSION_;
+       QFile playlistFile(filename);
+       if (playlistFile.exists()) {
+               playlistFile.remove();
+       }
+       QTextStream stream(&playlistFile);
+       stream << _PLAYLIST_SIGNATURE_ << endl;
+       const QList<Track> &tracks = playlist.tracks();
+       foreach (Track track, tracks) {
+               stream << _PLAYLIST_META_KEYWORD_ << " [" << track.metadata().length() << "],::" << track.metadata().artist()
+                               << "::,::" << track.metadata().album() << "::,::" << track.metadata().title() << "::" << endl;
+               stream << _PLAYLIST_PATH_KEYWORD_ << " " << track.source() << endl;
+       }
 }
 
 void FileStorage::removePlaylist(Playlist playlist) {
+       QString filename = _path_prefix + "/" + playlist.name() + "." + _PLAYLIST_FILE_EXTENSION_;
+       QFile file(filename);
+       file.remove();
 }
 
 void FileStorage::removePlaylist(QString name) {
+       QString filename = _path_prefix + "/" + name + "." + _PLAYLIST_FILE_EXTENSION_;
+       QFile file(filename);
+       file.remove();
 }
 
 Playlist FileStorage::getCurrentPlaylist() {
-       Playlist stub;
-       return stub;
+       return getPlaylist(_CURRENT_PLAYLIST_NAME_);
 }
 
 void FileStorage::saveCurrentPlaylist(Playlist playlist) {
+       playlist.setName(_CURRENT_PLAYLIST_NAME_);
+       savePlaylist(playlist);
 }
index 144828e..e8b8a23 100644 (file)
@@ -4,9 +4,23 @@
 #include "someplayer.h"
 #include "storage.h"
 #include "playlist.h"
+#include <QRegExp>
 
 #define _CURRENT_PLAYLIST_NAME_ "___current"
-#define _PLAYLIST_FILE_EXTENSION_ ".m3u"
+#define _PLAYLIST_FILE_EXTENSION_ "spls"
+#define _PLAYLIST_SIGNATURE_ "#SOMEPLAYLIST"
+#define _PLAYLIST_META_KEYWORD_ "#META"
+#define _PLAYLIST_PATH_KEYWORD_ "#PATH"
+
+// format:
+/*
+ #SOMEPLAYLIST
+ #META [seconds],::artist::,::album::,::title::
+ #PATH file_path
+ #META [seconds],::artist::,::album::,::title::
+ #PATH file_path
+ ...
+ */
 
 // represents file-level storage
 // it store data into separate files (e.g. playlist)
@@ -16,11 +30,13 @@ using SomePlayer::DataObjects::Playlist;
 namespace SomePlayer {
        namespace Storage {
 
-               class FileStorage : public Storage {
+               class FileStorage {
                public:
                        FileStorage(QString path);
 
                        QList<Playlist> getPlaylists();
+                       QStringList getPlaylistsNames();
+                       Playlist getPlaylist(QString name);
                        void savePlaylist(Playlist playlist);
                        void removePlaylist(Playlist playlist);
                        void removePlaylist(QString name);
@@ -29,6 +45,8 @@ namespace SomePlayer {
                        void saveCurrentPlaylist(Playlist playlist);
                private:
                        QString _path_prefix;
+                       QRegExp _meta_regexp;
+                       QRegExp _path_regexp;
                };
 
        };
index 5dcfaf4..54dcf09 100644 (file)
@@ -5,7 +5,6 @@ using namespace SomePlayer::Storage;
 
 #include "mediascanner.h"
 #include <QDir>
-#include <QDebug>
 
 Library::Library(QString databasePath, QString playlistsPath) : QObject(0) {
        _library_storage = new DbStorage(databasePath);
@@ -27,7 +26,8 @@ void Library::addDirectory(QString path) {
 }
 
 void Library::addFile(QString path) {
-       /// TODO: implement this
+       QStringList files(path);
+       _resolver->decode(files);
 }
 
 QList<QString> Library::getArtists() {
@@ -85,6 +85,14 @@ QList<Playlist> Library::getPlaylists() {
        return _playlist_storage->getPlaylists();
 }
 
+QStringList Library::getPlaylistsNames() {
+       return _playlist_storage->getPlaylistsNames();
+}
+
+Playlist Library::getPlaylist(QString name) {
+       return _playlist_storage->getPlaylist(name);
+}
+
 void Library::savePlaylist(Playlist playlist) {
        _playlist_storage->savePlaylist(playlist);
 }
@@ -93,6 +101,9 @@ void Library::removePlaylist(Playlist playlist) {
        _playlist_storage->removePlaylist(playlist);
 }
 
+void Library::removePlaylist(QString name) {
+       _playlist_storage->removePlaylist(name);
+}
 
 Playlist Library::getCurrentPlaylist() {
        return _playlist_storage->getCurrentPlaylist();
index 08414c3..36d3878 100644 (file)
@@ -41,8 +41,11 @@ namespace SomePlayer {
                        Playlist getRecentlyAdded();
 
                        QList<Playlist> getPlaylists();
+                       QStringList getPlaylistsNames();
+                       Playlist getPlaylist(QString name);
                        void savePlaylist(Playlist playlist);
                        void removePlaylist(Playlist playlist);
+                       void removePlaylist(QString name);
 
                        Playlist getCurrentPlaylist();
                        void saveCurrentPlaylist(Playlist playlist);
index 2c576f9..5038088 100644 (file)
@@ -4,6 +4,10 @@
 #include <QMessageBox>
 #include <QFile>
 
+#include "player.h"
+
+#include "library.h"
+
 MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
@@ -19,4 +23,6 @@ MainWindow::~MainWindow()
 
 void MainWindow::openMedia()
 {
+//     SomePlayer::DataObjects::Library *l = new SomePlayer::DataObjects::Library("/tmp", "/tmp");
+//     l->addDirectory("/mnt/music/Three Days Grace");
 }
index 000d35c..1f9adf0 100644 (file)
@@ -40,5 +40,5 @@ void MediaScanner::init(QString dir) {
        _initialized = true;
        if (!_iterator)
                delete _iterator;
-       _iterator = new QDirIterator(QDir(dir), QDirIterator::Subdirectories);
+       _iterator = new QDirIterator(QDir(dir), QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
 }
index 86a4ae6..a934bb1 100644 (file)
@@ -11,7 +11,7 @@ QString Playlist::name() const {
        return _name;
 }
 
-QList<Track> Playlist::tracks() const {
+const QList<Track> &Playlist::tracks() const {
        return _tracks;
 }
 
index 1e7b7fc..a937a3a 100644 (file)
@@ -13,7 +13,7 @@ namespace SomePlayer {
                        Playlist();
 
                        QString name() const;
-                       QList<Track> tracks() const;
+                       const QList<Track> &tracks() const;
 
                        void setName(QString name);
                        void addTrack(Track track);
diff --git a/src/storage.cpp b/src/storage.cpp
deleted file mode 100644 (file)
index 85252e6..0000000
+++ /dev/null
@@ -1 +0,0 @@
-#include "storage.h"
index 5f66bb1..76f1747 100644 (file)
@@ -3,15 +3,9 @@
 
 #include "someplayer.h"
 
-// represent abstract storage
-// abstract class
-
 namespace SomePlayer{
        namespace Storage {
 
-               class Storage {
-               };
-
        };
 };
 
index 8be3b86..ef579cd 100644 (file)
@@ -1,4 +1,5 @@
 #include "tagresolver.h"
+#include <QDebug>
 
 using namespace SomePlayer::DataObjects;
 
@@ -21,17 +22,16 @@ void TagResolver::decode(QStringList files) {
 
 void TagResolver::metaStateChanged(Phonon::State newState, Phonon::State /*oldState*/) {
        if (newState == Phonon::StoppedState) {
+               int time = _metaObject->totalTime();
                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);
-                       }
+               QMap<QString, QString> meta = _metaObject->metaData();
+               TrackMetadata metadata(meta.value("TITLE"), meta.value("ARTIST"), meta.value("ALBUM"), time/1000);
+               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);
                }
        }
 }
index 1a0a405..993711e 100644 (file)
@@ -9,24 +9,29 @@
 
 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;
+namespace SomePlayer {
+       namespace DataObjects {
 
-};
+               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 0cf35f4..087493c 100644 (file)
@@ -5,14 +5,16 @@ using namespace SomePlayer::DataObjects;
 TrackMetadata::TrackMetadata() {
 }
 
-TrackMetadata::TrackMetadata(QString title = "Unknown title", QString artist = "Unknown artist", QString album = "Unknown album") {
+TrackMetadata::TrackMetadata(QString title = "", QString artist = "", QString album = "", int length = 0) {
        _metadata["TITLE"] = title == "" ? "Unknown title" : title;
        _metadata["ARTIST"] = artist == "" ? "Unknown artist" : artist;
        _metadata["ALBUM"] = album == "" ? "Unknown album" : album;
+       _length = length;
 }
 
 TrackMetadata::TrackMetadata(const TrackMetadata &metadata) {
        this->_metadata = metadata._metadata;
+       this->_length = metadata._length;
 }
 
 QString TrackMetadata::title() {
@@ -39,6 +41,10 @@ QString TrackMetadata::album() {
        }
 }
 
+int TrackMetadata::length() {
+       return _length;
+}
+
 void TrackMetadata::setTitle(QString title) {
        _metadata["TITLE"] = title;
 }
@@ -50,3 +56,7 @@ void TrackMetadata::setArtist(QString artist) {
 void TrackMetadata::setAlbum(QString album) {
        _metadata["ALBUM"] = album;
 }
+
+void TrackMetadata::setLength(int length) {
+       _length = length;
+}
index 2496d19..29e0d49 100644 (file)
@@ -12,19 +12,22 @@ namespace SomePlayer {
 
                public:
                        TrackMetadata();
-                       TrackMetadata(QString title, QString artist, QString album);
+                       TrackMetadata(QString title, QString artist, QString album, int length);
                        TrackMetadata(const TrackMetadata &metadata);
 
                        QString title();
                        QString artist();
                        QString album();
+                       int length();
 
                        void setTitle(QString title);
                        void setArtist(QString artist);
                        void setAlbum(QString album);
+                       void setLength(int length);
 
                private:
                        QMap<QString, QString> _metadata;
+                       int _length;
                };
        };
 };