void HistoModel::addItem(MEDIA::TrackPtr media) { if( !media.isNull() ) { m_mutex.lock(); m_tracks.append(media); m_mutex.unlock(); } }
/******************************************************************************* LocalScene::rateTrack *******************************************************************************/ void LocalScene::rateTrack(QGraphicsItem* gi) { TrackGraphicItem *item = static_cast<TrackGraphicItem*>(gi); MEDIA::TrackPtr track = item->media; if(track->id != -1) { Database db; if (!db.connect()) return; QSqlQuery q("", *db.sqlDb()); q.prepare("UPDATE `tracks` SET `rating`=:rat WHERE `id`=:id;"); q.bindValue(":rat", track->rating ); q.bindValue(":id", track->id ); q.exec(); MEDIA::AlbumPtr album = MEDIA::AlbumPtr::staticCast(track->parent()); if(!album->isUserRating) album->rating = m_localTrackModel->getItemAutoRating(album); MEDIA::ArtistPtr artist = MEDIA::ArtistPtr::staticCast(album->parent()); if(!artist->isUserRating) artist->rating = m_localTrackModel->getItemAutoRating(artist); } }
//! ---------------- addToDatabase --------------------------------------------- void HistoManager::addToDatabase() { m_timer->stop(); if(Engine::instance()->state() != ENGINE::PLAYING) { m_timer->stop(); return; } MEDIA::TrackPtr media = m_player->playingTrack(); int now_date = QDateTime::currentDateTime().toTime_t(); QString engine_url = media->url; if(engine_url.isEmpty()) return; QString media_name; if(media->type() == TYPE_TRACK) media_name = media->artist + " - " + media->album + " - " + media->title; else media_name = media->name; Database db; if (!db.connect()) return; QSqlQuery("BEGIN TRANSACTION;",*db.sqlDb()); //--------------------------------------- // add or update entry in history //--------------------------------------- QSqlQuery q("", *db.sqlDb()); q.prepare("SELECT `id`,`url` FROM `histo` WHERE `url`=:val;"); q.bindValue(":val", engine_url ); q.exec(); if ( !q.next() ) { Debug::debug() << "[Histo] add a new entry" << engine_url; q.prepare("INSERT INTO `histo`(`url`,`name`,`date`) VALUES (:u,:n,:d);"); q.bindValue(":u", engine_url); q.bindValue(":n", media_name); q.bindValue(":d", now_date); q.exec(); if(q.numRowsAffected() < 1) Debug::warning() << "[Histo] error adding entry !! "; QSqlQuery query("DELETE FROM `histo` WHERE `id` <= (SELECT MAX(`id`) FROM `histo`) - 2000;", *db.sqlDb()); } else { Debug::debug() << "[Histo] update an existing entry" << engine_url; int histo_id = q.value(0).toString().toInt(); q.prepare("UPDATE `histo` SET `date`=:d WHERE `id`=:id;"); q.bindValue(":d", now_date); q.bindValue(":id", histo_id); q.exec(); } //--------------------------------------- // update playcount //--------------------------------------- q.prepare("SELECT `id`,`artist_id`,`album_id` FROM `view_tracks` WHERE `filename`=:val LIMIT 1;"); q.bindValue(":val", engine_url ); q.exec(); if (q.next()) { //Debug::debug() << "update playcount!"; const int trackId = q.value(0).toInt(); const int artistId = q.value(1).toInt(); const int albumId = q.value(2).toInt(); QSqlQuery query1("UPDATE `tracks` " \ "SET `playcount`=`playcount`+1 " \ "WHERE `id`="+QString::number(trackId)+";", *db.sqlDb()); QSqlQuery query2("UPDATE `albums` " \ "SET `playcount`=`playcount`+1 " \ "WHERE `id`="+QString::number(albumId)+";", *db.sqlDb()); QSqlQuery query3("UPDATE `artists` " \ "SET `playcount`=`playcount`+1 " \ "WHERE `id`="+QString::number(artistId)+";", *db.sqlDb()); /* update collection model item */ MEDIA::TrackPtr track = MEDIA::TrackPtr( LocalTrackModel::instance()->trackItemHash.value(trackId) ); if(!track.isNull()) { track->playcount++; track->lastPlayed = now_date; MEDIA::AlbumPtr album = MEDIA::AlbumPtr::staticCast(track->parent()); album->playcount++; MEDIA::ArtistPtr artist = MEDIA::ArtistPtr::staticCast(album->parent()); artist->playcount++; } } QSqlQuery("COMMIT TRANSACTION;",*db.sqlDb()); }
//! ------------------ HistoModel::updateModel --------------------------------- void HistoModel::updateModel() { Debug::debug() << " [HistoModel] updateModel"; this->clear(); if (!Database::instance()->open()) return; QSqlQuery query("SELECT id,url,name,date,track_id FROM view_histo ORDER BY date DESC",*Database::instance()->db()); while (query.next()) { QVariant track_id = query.value(4); QString url = query.value(1).toString(); if(!track_id.isNull()) { // increment pointer counter of mediaItem MEDIA::TrackPtr media = MEDIA::TrackPtr( LocalTrackModel::instance()->trackItemHash.value(track_id.toInt()) ); if(media) media->lastPlayed = (query.value(3).isNull() ? -1 : query.value(3).toInt()); addItem(media); } else { //! track or stream not id database if(MEDIA::isLocal(url)) { // do not search in file : to long for histo model !! MEDIA::TrackPtr media = MEDIA::TrackPtr(new MEDIA::Track()); media->id = -1; media->url = query.value(1).toString(); media->title = query.value(2).toString(); media->lastPlayed = (query.value(3).isNull() ? -1 : query.value(3).toInt()); //! default value media->isPlaying = false; media->isBroken = !QFile::exists(url); media->isPlayed = false; media->isStopAfter = false; addItem(media); } else { MEDIA::TrackPtr media = MEDIA::TrackPtr(new MEDIA::Track()); media->setType(TYPE_STREAM); media->id = -1; media->url = query.value(1).toString(); media->extra["station"] = query.value(2).toString(); media->lastPlayed = (query.value(3).isNull() ? -1 : query.value(3).toInt()); media->isFavorite = false; media->isPlaying = false; media->isBroken = false; media->isPlayed = false; media->isStopAfter = false; addItem(media); } } } // end while }
/******************************************************************************* .xspf playlist read *******************************************************************************/ QList<MEDIA::TrackPtr> readXspfPlaylist(QIODevice* device, const QDir& playlist_dir ) { Debug::debug() << "[MEDIA] readXspfPlaylist"; QList<MEDIA::TrackPtr> list; QXmlStreamReader xml(device); MEDIA::TrackPtr mi = MEDIA::TrackPtr(0); while(!xml.atEnd() && !xml.hasError()) { xml.readNext(); if (xml.isStartElement() && xml.name() == "trackList") break; } while (!xml.atEnd() && !xml.hasError()) { xml.readNext(); if (xml.isStartElement() && xml.name() == "track") { //Debug::debug() << "---- readXspfPlaylist -> NEW Track "; mi = MEDIA::TrackPtr(new MEDIA::Track()); } else if (xml.isStartElement() && xml.name() == "location") { QString file_path = QString(xml.readElementText()); //Debug::debug() << "---- readXspfPlaylist -> Find the Track location" << file_path; if (!MEDIA::isLocal(file_path)) { QUrl url(file_path); if (url.isValid()) { //Debug::debug() << "---- readXspfPlaylist -> it's an url"; if(mi) { mi->setType(TYPE_STREAM); mi->id = -1; mi->url = file_path; mi->name = file_path; mi->isFavorite = false; mi->isPlaying = false; mi->isBroken = false; mi->isPlayed = false; mi->isStopAfter = false; } } } else { //Debug::debug() << "---- readXspfPlaylist -> it's a local file"; file_path = QDir::fromNativeSeparators(file_path); //Debug::debug() << "---- readXspfPlaylist -> file_path" << file_path; // Make the path absolute if (!QDir::isAbsolutePath(file_path)) file_path = playlist_dir.absoluteFilePath(file_path); //Debug::debug() << "---- readXspfPlaylist -> file_path" << file_path; // Use the canonical path if (QFile::exists(file_path)) file_path = QFileInfo(file_path).canonicalFilePath(); //Debug::debug() << "---- readXspfPlaylist -> file_path" << file_path; if(mi) { mi->setType(TYPE_TRACK); mi->id = -1; mi->url = file_path; mi->isPlaying = false; mi->isBroken = !QFile::exists(file_path); mi->isPlayed = false; mi->isStopAfter = false; } } } // end location else if (xml.isStartElement() && xml.name() == "title") { if(mi->type() == TYPE_TRACK) mi->title = QString(xml.readElementText()); else mi->name = QString(xml.readElementText()); } else if (xml.isStartElement() && xml.name() == "category") { if(mi->type() == TYPE_STREAM) mi->categorie = QString(xml.readElementText()); } else if (xml.isEndElement() && xml.name() == "track") { //Debug::debug() << "---- readXspfPlaylist -> list.append(mi)" << mi; if(mi) list.append(mi); mi = MEDIA::TrackPtr(0); } } // End while xml end //Debug::debug() << "readXspfPlaylist -> END OK"; return list; }
/******************************************************************************* .pls playlist read *******************************************************************************/ QList<MEDIA::TrackPtr> readPlsPlaylist(QIODevice* device, const QDir& playlist_dir ) { Debug::debug() << "start readPlsPlaylist"; QList<MEDIA::TrackPtr> list; MEDIA::TrackPtr mi = MEDIA::TrackPtr(0); while (!device->atEnd()) { QString line = QString::fromUtf8(device->readLine()).trimmed(); int equals = line.indexOf('='); QString key = line.left(equals).toLower(); QString value = line.mid(equals + 1); if (key.startsWith("file")) { mi = MEDIA::TrackPtr(new MEDIA::Track()); list.append(mi); //! Find the Track location if (value.contains(QRegExp("^[a-z]+://"))) { QUrl url(value); if (url.isValid()) { // Debug::debug() << "---- readPlsPlaylist -> url.isValid()" << url; mi->setType(TYPE_STREAM); mi->id = -1; mi->url = value; mi->name = value; mi->isFavorite = false; mi->isPlaying = false; mi->isBroken = false; mi->isPlayed = false; mi->isStopAfter = false; } } else { QString file_path = value; file_path = QDir::fromNativeSeparators(file_path); // Make the path absolute if (!QDir::isAbsolutePath(file_path)) file_path = playlist_dir.absoluteFilePath(file_path); // Use the canonical path if (QFile::exists(file_path)) file_path = QFileInfo(file_path).canonicalFilePath(); mi->setType(TYPE_TRACK); mi->id = -1; mi->url = file_path; mi->isPlaying = false; mi->isBroken = QFile::exists(file_path) ? false : true; mi->isPlayed = false; mi->isStopAfter = false; } } // key is filename else if (key.startsWith("title")) { if(mi->type() == TYPE_TRACK) mi->title = value; else mi->name = value; } else if (key.startsWith("length")) { if(mi->type() == TYPE_TRACK) mi->duration = value.toInt(); } } // fin while Debug::debug() << "end readPlsPlaylist"; return list; }
/******************************************************************************* M3U playlist read *******************************************************************************/ QList<MEDIA::TrackPtr> readM3uPlaylist(QIODevice* device, const QDir& playlist_dir ) { QList<MEDIA::TrackPtr> list; QString data = QString::fromUtf8(device->readAll()); if(data.isEmpty()) return list; data.replace('\r', '\n'); data.replace("\n\n", "\n"); QByteArray bytes = data.toUtf8(); QBuffer buffer(&bytes); buffer.open(QIODevice::ReadOnly); //! metadata int lenght; QString title; QString artist; //! main reading loop QString line; while(!buffer.atEnd()) { line = QString::fromUtf8(buffer.readLine()).trimmed(); if(line.startsWith("#EXT")) { QString info = line.section(':', 1); QString l = info.section(',', 0, 0); /* TODO bool ok = false; int length = l.toInt(&ok); if (!ok) {lenght = -1; continue;} */ QString track_info = info.section(',', 1); QStringList list = track_info.split('-'); if (list.size() <= 1) { title = track_info; continue; } artist = list[0].trimmed(); title = list[1].trimmed(); } else if (line.startsWith('#')) { continue; } else if( !line.isEmpty() ) { //Debug::debug() << "---- readM3uPlaylist -> line " << line << "\n"; MEDIA::TrackPtr track = MEDIA::TrackPtr(new MEDIA::Track()); //! Find the Track location if (line.contains(QRegExp("^[a-z]+://"))) { QUrl url(line); if (url.isValid()) { track->setType(TYPE_STREAM); track->id = -1; track->url = url.toString(); track->name = title.isEmpty() ? url.toString() : title; track->isFavorite = false; track->isPlaying = false; track->isBroken = false; track->isPlayed = false; track->isStopAfter = false; list.append(track); } } else { QString file_path = line; file_path = QDir::fromNativeSeparators(file_path); // Make the path absolute if (!QDir::isAbsolutePath(file_path)) file_path = playlist_dir.absoluteFilePath(file_path); // Use the canonical path if (QFile::exists(file_path)) file_path = QFileInfo(file_path).canonicalFilePath(); track->setType(TYPE_TRACK); track->id = -1; track->url = file_path; track->title = title.isEmpty() ? QString() : title; track->duration = (lenght!=-1) ? lenght : 0; track->artist = artist.isEmpty() ? QString() : artist; track->isPlaying = false; track->isBroken = !QFile::exists(file_path); track->isPlayed = false; track->isStopAfter = false; track->albumGain = 0.0; track->albumPeak = 0.0; track->trackGain = 0.0; track->trackPeak = 0.0; list.append(track); } lenght = -1; title = ""; artist = ""; } } // end while return list; }
/******************************************************************************* PlaylistWidget::slot_add_to_playqueue *******************************************************************************/ void PlaylistWidget::slot_add_to_playqueue() { QAction *action = qobject_cast<QAction *>(sender()); if(!action) return; /*--------------------------------------------------*/ /* add file to playqueue */ /* -------------------------------------------------*/ if( action == m_actions->value(PLAYQUEUE_ADD_FILE) ) { FileDialog fd(this, FileDialog::AddFiles, tr("Add music files or playlist")); if(fd.exec() == QDialog::Accepted) { QStringList files = fd.addFiles(); m_model->manager()->playlistAddFiles(files); } } /*--------------------------------------------------*/ /* add dir to playqueue */ /* -------------------------------------------------*/ else if ( action == m_actions->value(PLAYQUEUE_ADD_DIR) ) { FileDialog fd(this, FileDialog::AddDirs, tr("Add music directories")); if(fd.exec() == QDialog::Accepted) { QStringList dirs = fd.addDirectories(); m_model->manager()->playlistAddFiles(dirs); } } /*--------------------------------------------------*/ /* add url to playqueue */ /* -------------------------------------------------*/ else if ( action == m_actions->value(PLAYQUEUE_ADD_URL) ) { AddStreamDialog stream_dialog(this,false); if(stream_dialog.exec() == QDialog::Accepted) { const QString url = stream_dialog.url(); if(!QUrl(url).isEmpty() && QUrl(url).isValid()) { const QString name = stream_dialog.name(); MEDIA::TrackPtr media = MEDIA::TrackPtr(new MEDIA::Track()); media->setType(TYPE_STREAM); media->id = -1; media->url = url; media->extra["station"] = !name.isEmpty() ? name : url ; media->isFavorite = false; media->isPlaying = false; media->isBroken = false; media->isPlayed = false; media->isStopAfter = false; m_model->addMediaItem(media); media.reset(); } else { StatusManager::instance()->startMessage("invalid url can not be added !!", STATUS::WARNING, 5000); } } } }