00001
00002 #include <QApplication>
00003 #include <QRegExp>
00004 #include <QDateTime>
00005 #include <QDir>
00006
00007
00008 #include <mythcontext.h>
00009 #include <mythwidgets.h>
00010 #include <mythdb.h>
00011 #include <mythdirs.h>
00012 #include <mythprogressdialog.h>
00013 #include <mythdownloadmanager.h>
00014 #include <mythlogging.h>
00015 #include <mythmiscutil.h>
00016
00017
00018 #include "metadata.h"
00019 #include "metaio.h"
00020 #include "metaioid3.h"
00021 #include "metaiomp4.h"
00022 #include "metaioavfcomment.h"
00023 #include "metaiooggvorbis.h"
00024 #include "metaioflacvorbis.h"
00025 #include "metaiowavpack.h"
00026 #include "playlist.h"
00027 #include "playlistcontainer.h"
00028 #include "musicutils.h"
00029
00030
00031
00032
00033 MusicData *gMusicData = NULL;
00034
00035 static QString thePrefix = "the ";
00036
00037 bool operator==(const Metadata& a, const Metadata& b)
00038 {
00039 if (a.Filename() == b.Filename())
00040 return true;
00041 return false;
00042 }
00043
00044 bool operator!=(const Metadata& a, const Metadata& b)
00045 {
00046 if (a.Filename() != b.Filename())
00047 return true;
00048 return false;
00049 }
00050
00051 Metadata::~Metadata()
00052 {
00053 if (m_albumArt)
00054 {
00055 delete m_albumArt;
00056 m_albumArt = NULL;
00057 }
00058 }
00059
00060
00061 Metadata& Metadata::operator=(const Metadata &rhs)
00062 {
00063 m_artist = rhs.m_artist;
00064 m_compilation_artist = rhs.m_compilation_artist;
00065 m_album = rhs.m_album;
00066 m_title = rhs.m_title;
00067 m_formattedartist = rhs.m_formattedartist;
00068 m_formattedtitle = rhs.m_formattedtitle;
00069 m_genre = rhs.m_genre;
00070 m_year = rhs.m_year;
00071 m_tracknum = rhs.m_tracknum;
00072 m_trackCount = rhs.m_trackCount;
00073 m_length = rhs.m_length;
00074 m_rating = rhs.m_rating;
00075 m_lastplay = rhs.m_lastplay;
00076 m_templastplay = rhs.m_templastplay;
00077 m_dateadded = rhs.m_dateadded;
00078 m_playcount = rhs.m_playcount;
00079 m_tempplaycount = rhs.m_tempplaycount;
00080 m_compilation = rhs.m_compilation;
00081 m_id = rhs.m_id;
00082 m_filename = rhs.m_filename;
00083 m_directoryid = rhs.m_directoryid;
00084 m_artistid = rhs.m_artistid;
00085 m_compartistid = rhs.m_compartistid;
00086 m_albumid = rhs.m_albumid;
00087 m_genreid = rhs.m_genreid;
00088 m_albumArt = NULL;
00089 m_format = rhs.m_format;
00090 m_changed = rhs.m_changed;
00091
00092 return *this;
00093 }
00094
00095 void Metadata::persist()
00096 {
00097 if (m_id < 1)
00098 return;
00099
00100 if (m_templastplay.isValid())
00101 {
00102 m_lastplay = m_templastplay;
00103 m_playcount = m_tempplaycount;
00104
00105 m_templastplay = QDateTime();
00106 }
00107
00108 MSqlQuery query(MSqlQuery::InitCon());
00109 query.prepare("UPDATE music_songs set rating = :RATING , "
00110 "numplays = :PLAYCOUNT , lastplay = :LASTPLAY "
00111 "where song_id = :ID ;");
00112 query.bindValue(":RATING", m_rating);
00113 query.bindValue(":PLAYCOUNT", m_playcount);
00114 query.bindValue(":LASTPLAY", m_lastplay);
00115 query.bindValue(":ID", m_id);
00116
00117 if (!query.exec())
00118 MythDB::DBError("music persist", query);
00119
00120 gPlayer->sendTrackStatsChangedEvent(ID());
00121
00122 m_changed = false;
00123 }
00124
00125
00126 void Metadata::UpdateModTime() const
00127 {
00128 if (m_id < 1)
00129 return;
00130
00131 MSqlQuery query(MSqlQuery::InitCon());
00132
00133 query.prepare("UPDATE music_songs SET date_modified = :DATE_MOD "
00134 "WHERE song_id= :ID ;");
00135
00136 query.bindValue(":DATE_MOD", QDateTime::currentDateTime());
00137 query.bindValue(":ID", m_id);
00138
00139 if (!query.exec())
00140 MythDB::DBError("Metadata::UpdateModTime",
00141 query);
00142 }
00143
00144 int Metadata::compare(const Metadata *other) const
00145 {
00146 if (m_format == "cast")
00147 {
00148 int artist_cmp = Artist().toLower().localeAwareCompare(
00149 other->Artist().toLower());
00150
00151 if (artist_cmp == 0)
00152 return Title().toLower().localeAwareCompare(
00153 other->Title().toLower());
00154
00155 return artist_cmp;
00156 }
00157 else
00158 {
00159 int track_cmp = Track() - other->Track();
00160
00161 if (track_cmp == 0)
00162 return Title().toLower().localeAwareCompare(
00163 other->Title().toLower());
00164
00165 return track_cmp;
00166 }
00167 }
00168
00169 bool Metadata::isInDatabase()
00170 {
00171 bool retval = false;
00172
00173 QString sqldir = m_filename.section('/', 0, -2);
00174 QString sqlfilename = m_filename.section('/', -1);
00175
00176 MSqlQuery query(MSqlQuery::InitCon());
00177 query.prepare("SELECT music_artists.artist_name, "
00178 "music_comp_artists.artist_name AS compilation_artist, "
00179 "music_albums.album_name, music_songs.name, music_genres.genre, "
00180 "music_songs.year, music_songs.track, music_songs.length, "
00181 "music_songs.song_id, music_songs.rating, music_songs.numplays, "
00182 "music_songs.lastplay, music_albums.compilation, music_songs.format, "
00183 "music_songs.track_count "
00184 "FROM music_songs "
00185 "LEFT JOIN music_directories "
00186 "ON music_songs.directory_id=music_directories.directory_id "
00187 "LEFT JOIN music_artists ON music_songs.artist_id=music_artists.artist_id "
00188 "LEFT JOIN music_albums ON music_songs.album_id=music_albums.album_id "
00189 "LEFT JOIN music_artists AS music_comp_artists "
00190 "ON music_albums.artist_id=music_comp_artists.artist_id "
00191 "LEFT JOIN music_genres ON music_songs.genre_id=music_genres.genre_id "
00192 "WHERE music_songs.filename = :FILENAME "
00193 "AND music_directories.path = :DIRECTORY ;");
00194 query.bindValue(":FILENAME", sqlfilename);
00195 query.bindValue(":DIRECTORY", sqldir);
00196
00197 if (query.exec() && query.next())
00198 {
00199
00200 m_artist = query.value(0).toString();
00201 m_compilation_artist = query.value(1).toString();
00202 m_album = query.value(2).toString();
00203 m_title = query.value(3).toString();
00204 m_genre = query.value(4).toString();
00205 m_year = query.value(5).toInt();
00206 m_tracknum = query.value(6).toInt();
00207 m_length = query.value(7).toInt();
00208 m_id = query.value(8).toUInt();
00209 m_rating = query.value(9).toInt();
00210 m_playcount = query.value(10).toInt();
00211 m_lastplay = query.value(11).toDateTime();
00212 m_compilation = (query.value(12).toInt() > 0);
00213 m_format = query.value(13).toString();
00214 m_trackCount = query.value(14).toInt();
00215
00216 retval = true;
00217 }
00218
00219 return retval;
00220 }
00221
00222 void Metadata::dumpToDatabase()
00223 {
00224 QString sqldir = m_filename.section('/', 0, -2);
00225 QString sqlfilename = m_filename.section('/', -1);
00226
00227 checkEmptyFields();
00228
00229 MSqlQuery query(MSqlQuery::InitCon());
00230
00231 if (sqldir.isEmpty())
00232 {
00233 m_directoryid = 0;
00234 }
00235 else if (m_directoryid < 0)
00236 {
00237
00238 query.prepare("SELECT directory_id FROM music_directories "
00239 "WHERE path = :DIRECTORY ;");
00240 query.bindValue(":DIRECTORY", sqldir);
00241
00242 if (!query.exec() || !query.isActive())
00243 {
00244 MythDB::DBError("music select directory id", query);
00245 return;
00246 }
00247 if (query.next())
00248 {
00249 m_directoryid = query.value(0).toInt();
00250 }
00251 else
00252 {
00253 query.prepare("INSERT INTO music_directories (path) VALUES (:DIRECTORY);");
00254 query.bindValue(":DIRECTORY", sqldir);
00255
00256 if (!query.exec() || !query.isActive() || query.numRowsAffected() <= 0)
00257 {
00258 MythDB::DBError("music insert directory", query);
00259 return;
00260 }
00261 m_directoryid = query.lastInsertId().toInt();
00262 }
00263 }
00264
00265 if (m_artistid < 0)
00266 {
00267
00268 query.prepare("SELECT artist_id FROM music_artists "
00269 "WHERE artist_name = :ARTIST ;");
00270 query.bindValue(":ARTIST", m_artist);
00271
00272 if (!query.exec() || !query.isActive())
00273 {
00274 MythDB::DBError("music select artist id", query);
00275 return;
00276 }
00277 if (query.next())
00278 {
00279 m_artistid = query.value(0).toInt();
00280 }
00281 else
00282 {
00283 query.prepare("INSERT INTO music_artists (artist_name) VALUES (:ARTIST);");
00284 query.bindValue(":ARTIST", m_artist);
00285
00286 if (!query.exec() || !query.isActive() || query.numRowsAffected() <= 0)
00287 {
00288 MythDB::DBError("music insert artist", query);
00289 return;
00290 }
00291 m_artistid = query.lastInsertId().toInt();
00292 }
00293 }
00294
00295
00296 if (m_artist == m_compilation_artist)
00297 {
00298 m_compartistid = m_artistid;
00299 }
00300 else
00301 {
00302 query.prepare("SELECT artist_id FROM music_artists "
00303 "WHERE artist_name = :ARTIST ;");
00304 query.bindValue(":ARTIST", m_compilation_artist);
00305 if (!query.exec() || !query.isActive())
00306 {
00307 MythDB::DBError("music select compilation artist id", query);
00308 return;
00309 }
00310 if (query.next())
00311 {
00312 m_compartistid = query.value(0).toInt();
00313 }
00314 else
00315 {
00316 query.prepare("INSERT INTO music_artists (artist_name) VALUES (:ARTIST);");
00317 query.bindValue(":ARTIST", m_compilation_artist);
00318
00319 if (!query.exec() || !query.isActive() || query.numRowsAffected() <= 0)
00320 {
00321 MythDB::DBError("music insert compilation artist", query);
00322 return;
00323 }
00324 m_compartistid = query.lastInsertId().toInt();
00325 }
00326 }
00327
00328
00329 if (m_albumid < 0)
00330 {
00331 query.prepare("SELECT album_id FROM music_albums "
00332 "WHERE artist_id = :COMP_ARTIST_ID "
00333 " AND album_name = :ALBUM ;");
00334 query.bindValue(":COMP_ARTIST_ID", m_compartistid);
00335 query.bindValue(":ALBUM", m_album);
00336 if (!query.exec() || !query.isActive())
00337 {
00338 MythDB::DBError("music select album id", query);
00339 return;
00340 }
00341 if (query.next())
00342 {
00343 m_albumid = query.value(0).toInt();
00344 }
00345 else
00346 {
00347 query.prepare("INSERT INTO music_albums (artist_id, album_name, compilation, year) VALUES (:COMP_ARTIST_ID, :ALBUM, :COMPILATION, :YEAR);");
00348 query.bindValue(":COMP_ARTIST_ID", m_compartistid);
00349 query.bindValue(":ALBUM", m_album);
00350 query.bindValue(":COMPILATION", m_compilation);
00351 query.bindValue(":YEAR", m_year);
00352
00353 if (!query.exec() || !query.isActive() || query.numRowsAffected() <= 0)
00354 {
00355 MythDB::DBError("music insert album", query);
00356 return;
00357 }
00358 m_albumid = query.lastInsertId().toInt();
00359 }
00360 }
00361
00362 if (m_genreid < 0)
00363 {
00364
00365 query.prepare("SELECT genre_id FROM music_genres "
00366 "WHERE genre = :GENRE ;");
00367 query.bindValue(":GENRE", m_genre);
00368 if (!query.exec() || !query.isActive())
00369 {
00370 MythDB::DBError("music select genre id", query);
00371 return;
00372 }
00373 if (query.next())
00374 {
00375 m_genreid = query.value(0).toInt();
00376 }
00377 else
00378 {
00379 query.prepare("INSERT INTO music_genres (genre) VALUES (:GENRE);");
00380 query.bindValue(":GENRE", m_genre);
00381
00382 if (!query.exec() || !query.isActive() || query.numRowsAffected() <= 0)
00383 {
00384 MythDB::DBError("music insert genre", query);
00385 return;
00386 }
00387 m_genreid = query.lastInsertId().toInt();
00388 }
00389 }
00390
00391
00392 QString strQuery;
00393 if (m_id < 1)
00394 {
00395 strQuery = "INSERT INTO music_songs ( directory_id,"
00396 " artist_id, album_id, name, genre_id,"
00397 " year, track, length, filename,"
00398 " rating, format, date_entered, date_modified,"
00399 " numplays, track_count) "
00400 "VALUES ( "
00401 " :DIRECTORY, "
00402 " :ARTIST, :ALBUM, :TITLE, :GENRE,"
00403 " :YEAR, :TRACKNUM, :LENGTH, :FILENAME,"
00404 " :RATING, :FORMAT, :DATE_ADD, :DATE_MOD,"
00405 " :PLAYCOUNT,:TRACKCOUNT );";
00406 }
00407 else
00408 {
00409 strQuery = "UPDATE music_songs SET"
00410 " directory_id = :DIRECTORY"
00411 ", artist_id = :ARTIST"
00412 ", album_id = :ALBUM"
00413 ", name = :TITLE"
00414 ", genre_id = :GENRE"
00415 ", year = :YEAR"
00416 ", track = :TRACKNUM"
00417 ", length = :LENGTH"
00418 ", filename = :FILENAME"
00419 ", rating = :RATING"
00420 ", format = :FORMAT"
00421 ", date_modified = :DATE_MOD "
00422 ", numplays = :PLAYCOUNT "
00423 ", track_count = :TRACKCOUNT "
00424 "WHERE song_id= :ID ;";
00425 }
00426
00427 query.prepare(strQuery);
00428
00429 query.bindValue(":DIRECTORY", m_directoryid);
00430 query.bindValue(":ARTIST", m_artistid);
00431 query.bindValue(":ALBUM", m_albumid);
00432 query.bindValue(":TITLE", m_title);
00433 query.bindValue(":GENRE", m_genreid);
00434 query.bindValue(":YEAR", m_year);
00435 query.bindValue(":TRACKNUM", m_tracknum);
00436 query.bindValue(":LENGTH", m_length);
00437 query.bindValue(":FILENAME", sqlfilename);
00438 query.bindValue(":RATING", m_rating);
00439 query.bindValue(":FORMAT", m_format);
00440 query.bindValue(":DATE_MOD", QDateTime::currentDateTime());
00441 query.bindValue(":PLAYCOUNT", m_playcount);
00442
00443 if (m_id < 1)
00444 query.bindValue(":DATE_ADD", QDateTime::currentDateTime());
00445 else
00446 query.bindValue(":ID", m_id);
00447
00448 query.bindValue(":TRACKCOUNT", m_trackCount);
00449
00450 if (!query.exec())
00451 MythDB::DBError("Metadata::dumpToDatabase - updating music_songs",
00452 query);
00453
00454 if (m_id < 1 && query.isActive() && 1 == query.numRowsAffected())
00455 m_id = query.lastInsertId().toInt();
00456
00457
00458 if (m_albumArt)
00459 m_albumArt->dumpToDatabase();
00460
00461
00462 query.prepare("UPDATE music_albums SET compilation = :COMPILATION, year = :YEAR "
00463 "WHERE music_albums.album_id = :ALBUMID");
00464 query.bindValue(":ALBUMID", m_albumid);
00465 query.bindValue(":COMPILATION", m_compilation);
00466 query.bindValue(":YEAR", m_year);
00467
00468 if (!query.exec() || !query.isActive())
00469 {
00470 MythDB::DBError("music compilation update", query);
00471 return;
00472 }
00473 }
00474
00475
00476
00477 QString Metadata::m_formatnormalfileartist = "ARTIST";
00478 QString Metadata::m_formatnormalfiletrack = "TITLE";
00479 QString Metadata::m_formatnormalcdartist = "ARTIST";
00480 QString Metadata::m_formatnormalcdtrack = "TITLE";
00481 QString Metadata::m_formatcompilationfileartist = "COMPARTIST";
00482 QString Metadata::m_formatcompilationfiletrack = "TITLE (ARTIST)";
00483 QString Metadata::m_formatcompilationcdartist = "COMPARTIST";
00484 QString Metadata::m_formatcompilationcdtrack = "TITLE (ARTIST)";
00485
00486 void Metadata::setArtistAndTrackFormats()
00487 {
00488 QString tmp;
00489
00490 tmp = gCoreContext->GetSetting("MusicFormatNormalFileArtist");
00491 if (!tmp.isEmpty())
00492 m_formatnormalfileartist = tmp;
00493
00494 tmp = gCoreContext->GetSetting("MusicFormatNormalFileTrack");
00495 if (!tmp.isEmpty())
00496 m_formatnormalfiletrack = tmp;
00497
00498 tmp = gCoreContext->GetSetting("MusicFormatNormalCDArtist");
00499 if (!tmp.isEmpty())
00500 m_formatnormalcdartist = tmp;
00501
00502 tmp = gCoreContext->GetSetting("MusicFormatNormalCDTrack");
00503 if (!tmp.isEmpty())
00504 m_formatnormalcdtrack = tmp;
00505
00506 tmp = gCoreContext->GetSetting("MusicFormatCompilationFileArtist");
00507 if (!tmp.isEmpty())
00508 m_formatcompilationfileartist = tmp;
00509
00510 tmp = gCoreContext->GetSetting("MusicFormatCompilationFileTrack");
00511 if (!tmp.isEmpty())
00512 m_formatcompilationfiletrack = tmp;
00513
00514 tmp = gCoreContext->GetSetting("MusicFormatCompilationCDArtist");
00515 if (!tmp.isEmpty())
00516 m_formatcompilationcdartist = tmp;
00517
00518 tmp = gCoreContext->GetSetting("MusicFormatCompilationCDTrack");
00519 if (!tmp.isEmpty())
00520 m_formatcompilationcdtrack = tmp;
00521 }
00522
00523
00524 bool Metadata::determineIfCompilation(bool cd)
00525 {
00526 m_compilation = (!m_compilation_artist.isEmpty()
00527 && m_artist != m_compilation_artist);
00528 setCompilationFormatting(cd);
00529 return m_compilation;
00530 }
00531
00532
00533 inline QString Metadata::formatReplaceSymbols(const QString &format)
00534 {
00535 QString rv = format;
00536 rv.replace("COMPARTIST", m_compilation_artist);
00537 rv.replace("ARTIST", m_artist);
00538 rv.replace("TITLE", m_title);
00539 rv.replace("TRACK", QString("%1").arg(m_tracknum, 2));
00540 return rv;
00541 }
00542
00543 void Metadata::checkEmptyFields()
00544 {
00545 if (m_artist.isEmpty())
00546 m_artist = QObject::tr("Unknown Artist");
00547
00548 if (!m_compilation || m_compilation_artist.isEmpty())
00549 m_compilation_artist = m_artist;
00550 if (m_album.isEmpty())
00551 m_album = QObject::tr("Unknown Album");
00552 if (m_title.isEmpty())
00553 m_title = m_filename;
00554 if (m_genre.isEmpty())
00555 m_genre = QObject::tr("Unknown Genre");
00556
00557 }
00558
00559 inline void Metadata::setCompilationFormatting(bool cd)
00560 {
00561 QString format_artist, format_title;
00562
00563 if (!m_compilation
00564 || "" == m_compilation_artist
00565 || m_artist == m_compilation_artist)
00566 {
00567 if (!cd)
00568 {
00569 format_artist = m_formatnormalfileartist;
00570 format_title = m_formatnormalfiletrack;
00571 }
00572 else
00573 {
00574 format_artist = m_formatnormalcdartist;
00575 format_title = m_formatnormalcdtrack;
00576 }
00577 }
00578 else
00579 {
00580 if (!cd)
00581 {
00582 format_artist = m_formatcompilationfileartist;
00583 format_title = m_formatcompilationfiletrack;
00584 }
00585 else
00586 {
00587 format_artist = m_formatcompilationcdartist;
00588 format_title = m_formatcompilationcdtrack;
00589 }
00590 }
00591
00592
00593 m_formattedartist = formatReplaceSymbols(format_artist);
00594 m_formattedtitle = formatReplaceSymbols(format_title);
00595 }
00596
00597
00598 QString Metadata::FormatArtist()
00599 {
00600 if (m_formattedartist.isEmpty())
00601 setCompilationFormatting();
00602
00603 return m_formattedartist;
00604 }
00605
00606
00607 QString Metadata::FormatTitle()
00608 {
00609 if (m_formattedtitle.isEmpty())
00610 setCompilationFormatting();
00611
00612 return m_formattedtitle;
00613 }
00614
00615 QString Metadata::Filename(bool find) const
00616 {
00617
00618 if (find == false)
00619 return m_filename;
00620
00621
00622 if (m_filename.endsWith(".cda"))
00623 return m_filename;
00624
00625
00626 if (m_filename.contains("://"))
00627 return m_filename;
00628
00629
00630 if (QFile::exists(m_filename))
00631 return m_filename;
00632
00633
00634 if (QFile::exists(gMusicData->musicDir + m_filename))
00635 return gMusicData->musicDir + m_filename;
00636
00637
00638
00639
00640
00641 LOG(VB_GENERAL, LOG_ERR, QString("Metadata: Asked to get the filename for a track but no file found: %1")
00642 .arg(m_filename));
00643 return QString();
00644 }
00645
00646 void Metadata::setField(const QString &field, const QString &data)
00647 {
00648 if (field == "artist")
00649 m_artist = data;
00650 else if (field == "compilation_artist")
00651 m_compilation_artist = data;
00652 else if (field == "album")
00653 m_album = data;
00654 else if (field == "title")
00655 m_title = data;
00656 else if (field == "genre")
00657 m_genre = data;
00658 else if (field == "filename")
00659 m_filename = data;
00660 else if (field == "year")
00661 m_year = data.toInt();
00662 else if (field == "tracknum")
00663 m_tracknum = data.toInt();
00664 else if (field == "trackcount")
00665 m_trackCount = data.toInt();
00666 else if (field == "length")
00667 m_length = data.toInt();
00668 else if (field == "compilation")
00669 m_compilation = (data.toInt() > 0);
00670
00671 else
00672 {
00673 LOG(VB_GENERAL, LOG_ERR, QString("Something asked me to set data "
00674 "for a field called %1").arg(field));
00675 }
00676 }
00677
00678 void Metadata::getField(const QString &field, QString *data)
00679 {
00680 if (field == "artist")
00681 *data = FormatArtist();
00682 else if (field == "album")
00683 *data = m_album;
00684 else if (field == "title")
00685 *data = FormatTitle();
00686 else if (field == "genre")
00687 *data = m_genre;
00688 else
00689 {
00690 LOG(VB_GENERAL, LOG_ERR, QString("Something asked me to return data "
00691 "about a field called %1").arg(field));
00692 *data = "I Dunno";
00693 }
00694 }
00695
00696 void Metadata::toMap(MetadataMap &metadataMap, const QString &prefix)
00697 {
00698 metadataMap[prefix + "artist"] = m_artist;
00699 metadataMap[prefix + "formatartist"] = FormatArtist();
00700 metadataMap[prefix + "compilationartist"] = m_compilation_artist;
00701 metadataMap[prefix + "album"] = m_album;
00702 metadataMap[prefix + "title"] = m_title;
00703 metadataMap[prefix + "formattitle"] = FormatTitle();
00704 metadataMap[prefix + "tracknum"] = (m_tracknum > 0 ? QString("%1").arg(m_tracknum) : "");
00705 metadataMap[prefix + "trackcount"] = (m_trackCount > 0 ? QString("%1").arg(m_trackCount) : "");
00706 metadataMap[prefix + "genre"] = m_genre;
00707 metadataMap[prefix + "year"] = (m_year > 0 ? QString("%1").arg(m_year) : "");
00708
00709 int len = m_length / 1000;
00710 int eh = len / 3600;
00711 int em = (len / 60) % 60;
00712 int es = len % 60;
00713 if (eh > 0)
00714 metadataMap[prefix + "length"] = QString().sprintf("%d:%02d:%02d", eh, em, es);
00715 else
00716 metadataMap[prefix + "length"] = QString().sprintf("%02d:%02d", em, es);
00717
00718 if (m_lastplay.isValid())
00719 metadataMap[prefix + "lastplayed"] = MythDateTimeToString(m_lastplay,
00720 kDateFull | kSimplify | kAddYear);
00721 else
00722 metadataMap[prefix + "lastplayed"] = QObject::tr("Never Played");
00723
00724 metadataMap[prefix + "dateadded"] = MythDateTimeToString(m_dateadded,
00725 kDateFull | kSimplify | kAddYear);
00726
00727 metadataMap[prefix + "playcount"] = QString::number(m_playcount);
00728
00729 metadataMap[prefix + "filename"] = gMusicData->musicDir + m_filename;
00730 }
00731
00732 void Metadata::decRating()
00733 {
00734 if (m_rating > 0)
00735 {
00736 m_rating--;
00737 }
00738 m_changed = true;
00739 }
00740
00741 void Metadata::incRating()
00742 {
00743 if (m_rating < 10)
00744 {
00745 m_rating++;
00746 }
00747 m_changed = true;
00748 }
00749
00750 void Metadata::setLastPlay()
00751 {
00752 m_templastplay = QDateTime::currentDateTime();
00753 m_changed = true;
00754 }
00755
00756 void Metadata::incPlayCount()
00757 {
00758 m_tempplaycount = m_playcount + 1;
00759 m_changed = true;
00760 }
00761
00762 void Metadata::setEmbeddedAlbumArt(AlbumArtList &albumart)
00763 {
00764
00765
00766 if (!m_albumArt)
00767 m_albumArt = new AlbumArtImages(this);
00768
00769 for (int x = 0; x < albumart.size(); x++)
00770 {
00771 m_albumArt->addImage(albumart.at(x));
00772 }
00773
00774 m_changed = true;
00775 }
00776
00777 QStringList Metadata::fillFieldList(QString field)
00778 {
00779 QStringList searchList;
00780 searchList.clear();
00781
00782 MSqlQuery query(MSqlQuery::InitCon());
00783 if ("artist" == field)
00784 {
00785 query.prepare("SELECT artist_name FROM music_artists ORDER BY artist_name;");
00786 }
00787 else if ("compilation_artist" == field)
00788 {
00789 query.prepare("SELECT DISTINCT artist_name FROM music_artists, music_albums where "
00790 "music_albums.artist_id=music_artists.artist_id ORDER BY artist_name");
00791 }
00792 else if ("album" == field)
00793 {
00794 query.prepare("SELECT album_name FROM music_albums ORDER BY album_name;");
00795 }
00796 else if ("title" == field)
00797 {
00798 query.prepare("SELECT name FROM music_songs ORDER BY name;");
00799 }
00800 else if ("genre" == field)
00801 {
00802 query.prepare("SELECT genre FROM music_genres ORDER BY genre;");
00803 }
00804 else
00805 {
00806 return searchList;
00807 }
00808
00809 if (query.exec() && query.isActive())
00810 {
00811 while (query.next())
00812 {
00813 searchList << query.value(0).toString();
00814 }
00815 }
00816 return searchList;
00817 }
00818
00819 QString Metadata::getAlbumArtFile(void)
00820 {
00821 if (!m_albumArt)
00822 m_albumArt = new AlbumArtImages(this);
00823
00824 AlbumArtImage *albumart_image = NULL;
00825 QString res;
00826
00827 if ((albumart_image = m_albumArt->getImage(IT_FRONTCOVER)))
00828 res = albumart_image->filename;
00829 else if ((albumart_image = m_albumArt->getImage(IT_UNKNOWN)))
00830 res = albumart_image->filename;
00831 else if ((albumart_image = m_albumArt->getImage(IT_BACKCOVER)))
00832 res = albumart_image->filename;
00833 else if ((albumart_image = m_albumArt->getImage(IT_INLAY)))
00834 res = albumart_image->filename;
00835 else if ((albumart_image = m_albumArt->getImage(IT_CD)))
00836 res = albumart_image->filename;
00837
00838
00839 if (!res.isEmpty())
00840 {
00841 int repo = ID_TO_REPO(m_id);
00842 if (repo == RT_Radio)
00843 {
00844
00845 QString path = GetConfDir() + "/MythMusic/AlbumArt/";
00846 QFileInfo fi(res);
00847 QString filename = QString("%1-%2.%3").arg(m_id).arg("front").arg(fi.suffix());
00848
00849 albumart_image->filename = path + filename;
00850
00851 if (!QFile::exists(albumart_image->filename))
00852 {
00853
00854 if (!GetMythDownloadManager()->download(res, albumart_image->filename))
00855 {
00856 m_albumArt->getImageList()->removeAll(albumart_image);
00857 return QString("");
00858 }
00859 }
00860
00861 res = albumart_image->filename;
00862 }
00863 else
00864 {
00865 if (!QFile::exists(res))
00866 {
00867 if (albumart_image->embedded && getTagger()->supportsEmbeddedImages())
00868 {
00869
00870 QImage *image = getTagger()->getAlbumArt(Filename(),
00871 albumart_image->imageType);
00872 if (image)
00873 {
00874 image->save(res);
00875 delete image;
00876 return res;
00877 }
00878 }
00879 else
00880 {
00881
00882 m_albumArt->getImageList()->removeAll(albumart_image);
00883 return QString("");
00884 }
00885 }
00886 }
00887
00888 return res;
00889 }
00890
00891 return QString("");
00892 }
00893
00894 QString Metadata::getAlbumArtFile(ImageType type)
00895 {
00896 if (!m_albumArt)
00897 m_albumArt = new AlbumArtImages(this);
00898
00899 AlbumArtImage *albumart_image = m_albumArt->getImage(type);
00900 if (albumart_image)
00901 return albumart_image->filename;
00902
00903 return QString("");
00904 }
00905
00906 AlbumArtImages *Metadata::getAlbumArtImages(void)
00907 {
00908 if (!m_albumArt)
00909 m_albumArt = new AlbumArtImages(this);
00910
00911 return m_albumArt;
00912 }
00913
00914 void Metadata::reloadAlbumArtImages(void)
00915 {
00916 delete m_albumArt;
00917 m_albumArt = NULL;
00918 }
00919
00920
00922 MetaIO* Metadata::getTagger(void)
00923 {
00924 static MetaIOID3 metaIOID3;
00925 static MetaIOOggVorbis metaIOOggVorbis;
00926 static MetaIOFLACVorbis metaIOFLACVorbis;
00927 static MetaIOMP4 metaIOMP4;
00928 static MetaIOWavPack metaIOWavPack;
00929 static MetaIOAVFComment metaIOAVFComment;
00930
00931 QFileInfo fi(m_filename);
00932 QString extension = fi.suffix();
00933
00934 if (extension == "mp3" || extension == "mp2")
00935 return &metaIOID3;
00936 else if (extension == "ogg" || extension == "oga")
00937 return &metaIOOggVorbis;
00938 else if (extension == "flac")
00939 {
00940 if (metaIOID3.TagExists(Filename(true)))
00941 return &metaIOID3;
00942 else
00943 return &metaIOFLACVorbis;
00944 }
00945 else if (extension == "m4a")
00946 return &metaIOMP4;
00947 else if (extension == "wv")
00948 return &metaIOWavPack;
00949 else
00950 return &metaIOAVFComment;
00951 }
00952
00953
00954
00955 MetadataLoadingThread::MetadataLoadingThread(AllMusic *parent_ptr) :
00956 MThread("MetadataLoading"), parent(parent_ptr)
00957 {
00958 }
00959
00960 void MetadataLoadingThread::run()
00961 {
00962 RunProlog();
00963
00964
00965 parent->resync();
00966 RunEpilog();
00967 }
00968
00969 AllMusic::AllMusic(void) :
00970 m_numPcs(0),
00971 m_numLoaded(0),
00972 m_metadata_loader(NULL),
00973 m_done_loading(false),
00974 m_last_listed(-1),
00975
00976 m_playcountMin(0),
00977 m_playcountMax(0),
00978 m_lastplayMin(0.0),
00979 m_lastplayMax(0.0)
00980 {
00981
00982 startLoading();
00983 }
00984
00985 AllMusic::~AllMusic()
00986 {
00987 while (!m_all_music.empty())
00988 {
00989 delete m_all_music.back();
00990 m_all_music.pop_back();
00991 }
00992
00993 while (!m_cdData.empty())
00994 {
00995 delete m_cdData.back();
00996 m_cdData.pop_back();
00997 }
00998
00999 m_metadata_loader->wait();
01000 delete m_metadata_loader;
01001 }
01002
01003 bool AllMusic::cleanOutThreads()
01004 {
01005
01006
01007
01008
01009 if (m_metadata_loader->isFinished())
01010 {
01011 return true;
01012 }
01013
01014 m_metadata_loader->wait();
01015 return false;
01016 }
01017
01029 bool AllMusic::startLoading(void)
01030 {
01031
01032
01033 m_done_loading = false;
01034
01035 if (m_metadata_loader)
01036 {
01037 cleanOutThreads();
01038 delete m_metadata_loader;
01039 }
01040
01041 m_metadata_loader = new MetadataLoadingThread(this);
01042 m_metadata_loader->start();
01043
01044 return true;
01045 }
01046
01047
01048
01049 void AllMusic::resync()
01050 {
01051 m_done_loading = false;
01052
01053 QString aquery = "SELECT music_songs.song_id, music_artists.artist_id, music_artists.artist_name, "
01054 "music_comp_artists.artist_name AS compilation_artist, "
01055 "music_albums.album_id, music_albums.album_name, music_songs.name, music_genres.genre, music_songs.year, "
01056 "music_songs.track, music_songs.length, music_songs.directory_id, "
01057 "CONCAT_WS('/', music_directories.path, music_songs.filename) AS filename, "
01058 "music_songs.rating, music_songs.numplays, music_songs.lastplay, music_songs.date_entered, "
01059 "music_albums.compilation, music_songs.format, music_songs.track_count "
01060 "FROM music_songs "
01061 "LEFT JOIN music_directories ON music_songs.directory_id=music_directories.directory_id "
01062 "LEFT JOIN music_artists ON music_songs.artist_id=music_artists.artist_id "
01063 "LEFT JOIN music_albums ON music_songs.album_id=music_albums.album_id "
01064 "LEFT JOIN music_artists AS music_comp_artists ON music_albums.artist_id=music_comp_artists.artist_id "
01065 "LEFT JOIN music_genres ON music_songs.genre_id=music_genres.genre_id "
01066 "ORDER BY music_songs.song_id;";
01067
01068 QString filename, artist, album, title, compartist;
01069
01070 MSqlQuery query(MSqlQuery::InitCon());
01071 if (!query.exec(aquery))
01072 MythDB::DBError("AllMusic::resync", query);
01073
01074 m_numPcs = query.size() * 2;
01075 m_numLoaded = 0;
01076
01077 if (query.isActive() && query.size() > 0)
01078 {
01079 while (query.next())
01080 {
01081 int id = query.value(0).toInt();
01082
01083 if (!music_map.contains(id))
01084 {
01085 filename = query.value(12).toString();
01086
01087 Metadata *mdata = new Metadata(
01088 filename,
01089 query.value(2).toString(),
01090 query.value(3).toString(),
01091 query.value(5).toString(),
01092 query.value(6).toString(),
01093 query.value(7).toString(),
01094 query.value(8).toInt(),
01095 query.value(9).toInt(),
01096 query.value(10).toInt(),
01097 query.value(0).toInt(),
01098 query.value(13).toInt(),
01099 query.value(14).toInt(),
01100 query.value(15).toDateTime(),
01101 query.value(16).toDateTime(),
01102 (query.value(17).toInt() > 0),
01103 query.value(18).toString());
01104
01105 mdata->setDirectoryId(query.value(11).toInt());
01106 mdata->setArtistId(query.value(1).toInt());
01107 mdata->setAlbumId(query.value(4).toInt());
01108 mdata->setTrackCount(query.value(19).toInt());
01109
01110
01111 m_all_music.append(mdata);
01112
01113 music_map[id] = mdata;
01114 }
01115
01116
01117 if (query.at() == 0)
01118 {
01119
01120 m_playcountMin = m_playcountMax = query.value(13).toInt();
01121 m_lastplayMin = m_lastplayMax = query.value(14).toDateTime().toTime_t();
01122 }
01123 else
01124 {
01125 int playCount = query.value(13).toInt();
01126 double lastPlay = query.value(14).toDateTime().toTime_t();
01127
01128 m_playcountMin = min(playCount, m_playcountMin);
01129 m_playcountMax = max(playCount, m_playcountMax);
01130 m_lastplayMin = min(lastPlay, m_lastplayMin);
01131 m_lastplayMax = max(lastPlay, m_lastplayMax);
01132 }
01133 m_numLoaded++;
01134 }
01135 }
01136 else
01137 {
01138 LOG(VB_GENERAL, LOG_ERR, "MythMusic hasn't found any tracks! "
01139 "That's ok with me if it's ok with you.");
01140 }
01141
01142 m_done_loading = true;
01143 }
01144
01145 Metadata* AllMusic::getMetadata(int an_id)
01146 {
01147 if (music_map.contains(an_id))
01148 return music_map[an_id];
01149
01150 return NULL;
01151 }
01152
01153 bool AllMusic::isValidID(int an_id)
01154 {
01155 return music_map.contains(an_id);
01156 }
01157
01158 bool AllMusic::updateMetadata(int an_id, Metadata *the_track)
01159 {
01160 if (an_id > 0)
01161 {
01162 Metadata *mdata = getMetadata(an_id);
01163 if (mdata)
01164 {
01165 *mdata = *the_track;
01166 return true;
01167 }
01168 }
01169 return false;
01170 }
01171
01173 void AllMusic::save(void)
01174 {
01175 MetadataPtrList::iterator it = m_all_music.begin();
01176 for (; it != m_all_music.end(); ++it)
01177 {
01178 if ((*it)->hasChanged())
01179 (*it)->persist();
01180 }
01181 }
01182
01183
01184 void AllMusic::clearCDData(void)
01185 {
01186 while (!m_cdData.empty())
01187 {
01188 delete m_cdData.back();
01189 m_cdData.pop_back();
01190 }
01191
01192 m_cdTitle = QObject::tr("CD -- none");
01193 }
01194
01195 void AllMusic::addCDTrack(const Metadata &the_track)
01196 {
01197 Metadata *mdata = new Metadata(the_track);
01198 mdata->setID(m_cdData.count() + 1);
01199 mdata->setRepo(RT_CD);
01200 m_cdData.append(mdata);
01201 music_map[mdata->ID()] = mdata;
01202 }
01203
01204 bool AllMusic::checkCDTrack(Metadata *the_track)
01205 {
01206 if (m_cdData.count() < 1)
01207 return false;
01208
01209 if (m_cdData.last()->FormatTitle() == the_track->FormatTitle())
01210 return true;
01211
01212 return false;
01213 }
01214
01215 Metadata* AllMusic::getCDMetadata(int the_track)
01216 {
01217 MetadataPtrList::iterator anit;
01218 for (anit = m_cdData.begin(); anit != m_cdData.end(); ++anit)
01219 {
01220 if ((*anit)->Track() == the_track)
01221 {
01222 return (*anit);
01223 }
01224 }
01225
01226 return NULL;
01227 }
01228
01229
01230
01231
01232 AlbumArtImages::AlbumArtImages(Metadata *metadata)
01233 : m_parent(metadata)
01234 {
01235 findImages();
01236 }
01237
01238 AlbumArtImages::~AlbumArtImages()
01239 {
01240 while (!m_imageList.empty())
01241 {
01242 delete m_imageList.back();
01243 m_imageList.pop_back();
01244 }
01245 }
01246
01247 void AlbumArtImages::findImages(void)
01248 {
01249 while (!m_imageList.empty())
01250 {
01251 delete m_imageList.back();
01252 m_imageList.pop_back();
01253 }
01254
01255 if (m_parent == NULL)
01256 return;
01257
01258 int trackid = ID_TO_ID(m_parent->ID());
01259 int repo = ID_TO_REPO(m_parent->ID());
01260
01261 if (repo == RT_Radio)
01262 {
01263 MSqlQuery query(MSqlQuery::InitCon());
01264 query.prepare("SELECT logourl FROM music_radios WHERE intid = :ID;");
01265 query.bindValue(":ID", trackid);
01266 if (query.exec())
01267 {
01268 while (query.next())
01269 {
01270 QString logoUrl = query.value(0).toString();
01271 AlbumArtImage *image = new AlbumArtImage();
01272 image->id = -1;
01273 image->filename = logoUrl;
01274 image->imageType = IT_FRONTCOVER;
01275 image->embedded = false;
01276
01277 m_imageList.push_back(image);
01278 }
01279 }
01280 }
01281 else
01282 {
01283 if (trackid == 0)
01284 return;
01285
01286 QFileInfo fi(m_parent->Filename(false));
01287 QString dir = fi.path();
01288
01289 MSqlQuery query(MSqlQuery::InitCon());
01290 query.prepare("SELECT albumart_id, CONCAT_WS('/', music_directories.path, "
01291 "music_albumart.filename), music_albumart.filename, music_albumart.imagetype, "
01292 "music_albumart.embedded "
01293 "FROM music_albumart "
01294 "LEFT JOIN music_directories ON "
01295 "music_directories.directory_id = music_albumart.directory_id "
01296 "WHERE music_directories.path = :DIR "
01297 "OR song_id = :SONGID "
01298 "ORDER BY music_albumart.imagetype;");
01299 query.bindValue(":DIR", dir);
01300 query.bindValue(":SONGID", trackid);
01301 if (query.exec())
01302 {
01303 while (query.next())
01304 {
01305 AlbumArtImage *image = new AlbumArtImage();
01306 bool embedded = (query.value(4).toInt() == 1);
01307 image->id = query.value(0).toInt();
01308
01309 if (embedded)
01310 image->filename = GetConfDir() + "/MythMusic/AlbumArt/" + query.value(1).toString();
01311 else
01312 image->filename = gMusicData->musicDir + query.value(1).toString();
01313
01314 image->imageType = (ImageType) query.value(3).toInt();
01315 image->embedded = embedded;
01316
01317 m_imageList.push_back(image);
01318 }
01319 }
01320
01321
01322 QString artist = m_parent->Artist().toLower();
01323 if (findIcon("artist", artist) != QString())
01324 {
01325 AlbumArtImage *image = new AlbumArtImage();
01326 image->id = -1;
01327 image->filename = findIcon("artist", artist);
01328 image->imageType = IT_ARTIST;
01329 image->embedded = false;
01330
01331 m_imageList.push_back(image);
01332 }
01333 }
01334 }
01335
01336 AlbumArtImage *AlbumArtImages::getImage(ImageType type)
01337 {
01338 AlbumArtList::iterator it = m_imageList.begin();
01339 for (; it != m_imageList.end(); ++it)
01340 {
01341 if ((*it)->imageType == type)
01342 return *it;
01343 }
01344
01345 return NULL;
01346 }
01347
01348 QStringList AlbumArtImages::getImageFilenames(void) const
01349 {
01350 QStringList paths;
01351
01352 AlbumArtList::const_iterator it = m_imageList.begin();
01353 for (; it != m_imageList.end(); ++it)
01354 paths += (*it)->filename;
01355
01356 return paths;
01357 }
01358
01359 AlbumArtImage *AlbumArtImages::getImageAt(uint index)
01360 {
01361 if (index < (uint)m_imageList.size())
01362 return m_imageList[index];
01363
01364 return NULL;
01365 }
01366
01367
01368 QString AlbumArtImages::getTypeName(ImageType type)
01369 {
01370
01371 static const char* type_strings[] = {
01372 QT_TR_NOOP("Unknown"),
01373 QT_TR_NOOP("Front Cover"),
01374 QT_TR_NOOP("Back Cover"),
01375 QT_TR_NOOP("CD"),
01376 QT_TR_NOOP("Inlay"),
01377 QT_TR_NOOP("Artist"),
01378 };
01379
01380 return QCoreApplication::translate("AlbumArtImages",
01381 type_strings[type]);
01382 }
01383
01384
01385 QString AlbumArtImages::getTypeFilename(ImageType type)
01386 {
01387
01388 static const char* filename_strings[] = {
01389 QT_TR_NOOP("unknown"),
01390 QT_TR_NOOP("front"),
01391 QT_TR_NOOP("back"),
01392 QT_TR_NOOP("cd"),
01393 QT_TR_NOOP("inlay"),
01394 QT_TR_NOOP("artist")
01395 };
01396
01397 return QCoreApplication::translate("AlbumArtImages",
01398 filename_strings[type]);
01399 }
01400
01401
01402 ImageType AlbumArtImages::guessImageType(const QString &filename)
01403 {
01404 ImageType type = IT_FRONTCOVER;
01405
01406 if (filename.contains("front", Qt::CaseInsensitive) ||
01407 filename.contains(QObject::tr("front"), Qt::CaseInsensitive))
01408 type = IT_FRONTCOVER;
01409 else if (filename.contains("back", Qt::CaseInsensitive) ||
01410 filename.contains(QObject::tr("back"), Qt::CaseInsensitive))
01411 type = IT_BACKCOVER;
01412 else if (filename.contains("inlay", Qt::CaseInsensitive) ||
01413 filename.contains(QObject::tr("inlay"), Qt::CaseInsensitive))
01414 type = IT_INLAY;
01415 else if (filename.contains("cd", Qt::CaseInsensitive) ||
01416 filename.contains(QObject::tr("cd"), Qt::CaseInsensitive))
01417 type = IT_CD;
01418 else if (filename.contains("cover", Qt::CaseInsensitive) ||
01419 filename.contains(QObject::tr("cover"), Qt::CaseInsensitive))
01420 type = IT_FRONTCOVER;
01421
01422 return type;
01423 }
01424
01425 void AlbumArtImages::addImage(const AlbumArtImage &newImage)
01426 {
01427
01428 AlbumArtImage *image = NULL;
01429
01430 AlbumArtList::iterator it = m_imageList.begin();
01431 for (; it != m_imageList.end(); ++it)
01432 {
01433 if ((*it)->imageType == newImage.imageType && (*it)->embedded == newImage.embedded)
01434 {
01435 image = *it;
01436 break;
01437 }
01438 }
01439
01440 if (!image)
01441 {
01442
01443 image = new AlbumArtImage(newImage);
01444 m_imageList.push_back(image);
01445 }
01446 else
01447 {
01448
01449 image->filename = newImage.filename;
01450 image->imageType = newImage.imageType;
01451 image->embedded = newImage.embedded;
01452 image->description = newImage.description;
01453 }
01454
01455
01456 if (image->embedded && m_parent->getTagger()->supportsEmbeddedImages())
01457 {
01458 QString path = GetConfDir() + "/MythMusic/AlbumArt/";
01459 QDir dir(path);
01460
01461 QString filename = QString("%1-%2.jpg").arg(m_parent->ID()).arg(AlbumArtImages::getTypeFilename(image->imageType));
01462 if (!QFile::exists(path + filename))
01463 {
01464 if (!dir.exists())
01465 dir.mkpath(path);
01466
01467 QImage *saveImage = m_parent->getTagger()->getAlbumArt(m_parent->Filename(), image->imageType);
01468 if (saveImage)
01469 {
01470 saveImage->save(path + filename, "JPEG");
01471 delete saveImage;
01472 }
01473 }
01474
01475 image->filename = path + filename;
01476 }
01477 }
01478
01480 void AlbumArtImages::dumpToDatabase(void)
01481 {
01482 Metadata::IdType trackID = ID_TO_ID(m_parent->ID());
01483 int directoryID = m_parent->getDirectoryId();
01484
01485
01486 if (trackID == 0 || directoryID == -1)
01487 {
01488 LOG(VB_GENERAL, LOG_ERR, "AlbumArtImages: Asked to save to the DB but "
01489 "have invalid songid or directoryid");
01490 return;
01491 }
01492
01493 MSqlQuery query(MSqlQuery::InitCon());
01494
01495
01496 query.prepare("DELETE FROM music_albumart "
01497 "WHERE song_id = :SONGID "
01498 "OR (embedded = 0 AND directory_id = :DIRECTORYID)");
01499
01500 query.bindValue(":SONGID", trackID);
01501 query.bindValue(":DIRECTORYID", directoryID);
01502
01503 query.exec();
01504
01505
01506 AlbumArtList::iterator it = m_imageList.begin();
01507 for (; it != m_imageList.end(); ++it)
01508 {
01509 AlbumArtImage *image = (*it);
01510
01511
01512 if (image->imageType == IT_ARTIST)
01513 continue;
01514
01515 if (image->id > 0)
01516 {
01517
01518 query.prepare("INSERT INTO music_albumart ( albumart_id, "
01519 "filename, imagetype, song_id, directory_id, embedded ) "
01520 "VALUES ( :ID, :FILENAME, :TYPE, :SONGID, :DIRECTORYID, :EMBED );");
01521 query.bindValue(":ID", image->id);
01522 }
01523 else
01524 {
01525 query.prepare("INSERT INTO music_albumart ( filename, "
01526 "imagetype, song_id, directory_id, embedded ) VALUES ( "
01527 ":FILENAME, :TYPE, :SONGID, :DIRECTORYID, :EMBED );");
01528 }
01529
01530 QFileInfo fi(image->filename);
01531 query.bindValue(":FILENAME", fi.fileName());
01532
01533 query.bindValue(":TYPE", image->imageType);
01534 query.bindValue(":SONGID", image->embedded ? trackID : 0);
01535 query.bindValue(":DIRECTORYID", image->embedded ? 0 : directoryID);
01536 query.bindValue(":EMBED", image->embedded);
01537
01538 if (!query.exec())
01539 MythDB::DBError("AlbumArtImages::dumpToDatabase - "
01540 "add/update music_albumart", query);
01541 }
01542 }
01543
01544
01545
01546
01547 MusicData::MusicData(void)
01548 {
01549 all_playlists = NULL;
01550 all_music = NULL;
01551 initialized = false;
01552 }
01553
01554 MusicData::~MusicData(void)
01555 {
01556 if (all_playlists)
01557 {
01558 delete all_playlists;
01559 all_playlists = NULL;
01560 }
01561
01562 if (all_music)
01563 {
01564 delete all_music;
01565 all_music = NULL;
01566 }
01567 }
01568
01570 void MusicData::reloadMusic(void)
01571 {
01572 if (!all_music || !all_playlists)
01573 return;
01574
01575 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
01576 QString message = QObject::tr("Rebuilding music tree");
01577
01578 MythUIBusyDialog *busy = new MythUIBusyDialog(message, popupStack,
01579 "musicscanbusydialog");
01580
01581 if (busy->Create())
01582 popupStack->AddScreen(busy, false);
01583 else
01584 busy = NULL;
01585
01586 all_music->startLoading();
01587 while (!all_music->doneLoading())
01588 {
01589 qApp->processEvents();
01590 usleep(50000);
01591 }
01592 all_playlists->postLoad();
01593
01594 if (busy)
01595 busy->Close();
01596 }
01597