Go to the documentation of this file.
5 #include <QApplication>
8 #include <QDomDocument>
10 #include <QScopedPointer>
59 const UrlList &lurls, QString llogourl, QString lgenre, QString lmetaformat,
60 QString lcountry, QString llanguage, QString lformat)
61 : m_genre(std::move(lgenre)),
62 m_format(std::move(lformat)),
65 m_broadcaster(std::move(lbroadcaster)),
66 m_channel(std::move(lchannel)),
67 m_description(std::move(ldescription)),
68 m_logoUrl(std::move(llogourl)),
69 m_metaFormat(std::move(lmetaformat)),
70 m_country(std::move(lcountry)),
71 m_language(std::move(llanguage))
193 query.
prepare(
"UPDATE music_songs set rating = :RATING , "
194 "numplays = :PLAYCOUNT , lastplay = :LASTPLAY "
195 "where song_id = :ID ;");
213 query.
prepare(
"UPDATE music_songs SET hostname = :HOSTNAME "
214 "WHERE song_id = :ID ;");
226 QString sqldir =
filename.section(
'/', 0, -2);
228 QString sqlfilename =
filename.section(
'/', -1);
232 "SELECT song_id FROM music_songs "
233 "LEFT JOIN music_directories ON music_songs.directory_id=music_directories.directory_id "
234 "WHERE music_songs.filename = :FILENAME "
235 "AND music_directories.path = :DIRECTORY ;");
247 LOG(VB_GENERAL, LOG_WARNING,
248 QString(
"MusicMetadata::createFromFilename: Could not find '%1'")
263 "music_comp_artists.artist_name AS compilation_artist, "
264 "music_albums.album_name, music_songs.name, music_genres.genre, "
265 "music_songs.year, music_songs.track, music_songs.length, "
266 "music_songs.song_id, music_songs.rating, music_songs.numplays, "
267 "music_songs.lastplay, music_albums.compilation, music_songs.format, "
268 "music_songs.track_count, music_songs.size, music_songs.date_entered, "
269 "music_songs.disc_number, music_songs.disc_count, "
270 "CONCAT_WS('/', music_directories.path, music_songs.filename) AS filename, "
271 "music_songs.hostname "
273 "LEFT JOIN music_directories ON music_songs.directory_id=music_directories.directory_id "
274 "LEFT JOIN music_artists ON music_songs.artist_id=music_artists.artist_id "
275 "LEFT JOIN music_albums ON music_songs.album_id=music_albums.album_id "
276 "LEFT JOIN music_artists AS music_comp_artists ON music_albums.artist_id=music_comp_artists.artist_id "
277 "LEFT JOIN music_genres ON music_songs.genre_id=music_genres.genre_id "
278 "WHERE music_songs.song_id = :SONGID; ");
285 mdata->m_compilationArtist =
query.
value(1).toString();
295 mdata->m_lastPlay =
query.
value(11).toDateTime();
296 mdata->m_compilation = (
query.
value(12).toInt() > 0);
298 mdata->m_trackCount =
query.
value(14).toInt();
299 mdata->m_fileSize =
query.
value(15).toULongLong();
300 mdata->m_dateAdded =
query.
value(16).toDateTime();
303 mdata->m_filename =
query.
value(19).toString();
304 mdata->m_hostname =
query.
value(20).toString();
305 mdata->ensureSortFields();
307 if (!QHostAddress(mdata->m_hostname).isNull())
309 mdata->m_hostname =
"";
310 mdata->saveHostname();
328 LOG(VB_GENERAL, LOG_ERR,
"MusicMetadata: looks like we are already updating the radio streams list");
332 QByteArray compressedData;
333 QByteArray uncompressedData;
342 LOG(VB_GENERAL, LOG_INFO,
"MusicMetadata: radio streams list is already up to date");
348 LOG(VB_GENERAL, LOG_INFO,
"MusicMetadata: downloading radio streams list");
353 LOG(VB_GENERAL, LOG_ERR,
"MusicMetadata: failed to download radio stream list");
368 if (!domDoc.setContent(uncompressedData,
false, &errorMsg,
369 &errorLine, &errorColumn))
371 LOG(VB_GENERAL, LOG_ERR,
372 "MusicMetadata: Could not read content of streams.xml" +
374 QString(
"\n\t\t\tat line: %1 column: %2 msg: %3")
375 .
arg(errorLine).
arg(errorColumn).
arg(errorMsg));
389 LOG(VB_GENERAL, LOG_INFO,
"MusicMetadata: processing radio streams list");
391 QDomNodeList itemList = domDoc.elementsByTagName(
"item");
394 for (
int i = 0; i < itemList.count(); i++)
396 itemNode = itemList.item(i);
398 query.
prepare(
"INSERT INTO music_streams (broadcaster, channel, description, url1, url2, url3, url4, url5,"
399 " logourl, genre, metaformat, country, language) "
400 "VALUES (:BROADCASTER, :CHANNEL, :DESC, :URL1, :URL2, :URL3, :URL4, :URL5,"
401 " :LOGOURL, :GENRE, :META, :COUNTRY, :LANG);");
403 query.
bindValue(
":BROADCASTER", itemNode.namedItem(QString(
"broadcaster")).toElement().text());
404 query.
bindValue(
":CHANNEL", itemNode.namedItem(QString(
"channel")).toElement().text());
405 query.
bindValue(
":DESC", itemNode.namedItem(QString(
"description")).toElement().text());
406 query.
bindValue(
":URL1", itemNode.namedItem(QString(
"url1")).toElement().text());
407 query.
bindValue(
":URL2", itemNode.namedItem(QString(
"url2")).toElement().text());
408 query.
bindValue(
":URL3", itemNode.namedItem(QString(
"url3")).toElement().text());
409 query.
bindValue(
":URL4", itemNode.namedItem(QString(
"url4")).toElement().text());
410 query.
bindValue(
":URL5", itemNode.namedItem(QString(
"url5")).toElement().text());
411 query.
bindValue(
":LOGOURL", itemNode.namedItem(QString(
"logourl")).toElement().text());
412 query.
bindValue(
":GENRE", itemNode.namedItem(QString(
"genre")).toElement().text());
413 query.
bindValue(
":META", itemNode.namedItem(QString(
"metadataformat")).toElement().text());
414 query.
bindValue(
":COUNTRY", itemNode.namedItem(QString(
"country")).toElement().text());
415 query.
bindValue(
":LANG", itemNode.namedItem(QString(
"language")).toElement().text());
427 LOG(VB_GENERAL, LOG_INFO,
"MusicMetadata: updating radio streams list completed OK");
438 LOG(VB_GENERAL, LOG_ERR, QString(
"MusicMetadata: Asked to reload metadata "
439 "for trackID: %1 but not found!").
arg(
m_id));
459 QString sqldir =
m_filename.section(
'/', 0, -2);
465 if (sqldir.isEmpty())
472 query.
prepare(
"SELECT directory_id FROM music_directories "
473 "WHERE path = :DIRECTORY ;");
487 query.
prepare(
"INSERT INTO music_directories (path) VALUES (:DIRECTORY);");
511 "WHERE artist_name = :ARTIST ;");
525 query.
prepare(
"INSERT INTO music_artists (artist_name) VALUES (:ARTIST);");
553 "WHERE artist_name = :ARTIST ;");
566 query.
prepare(
"INSERT INTO music_artists (artist_name) VALUES (:ARTIST);");
589 "WHERE artist_id = :COMP_ARTIST_ID "
590 " AND album_name = :ALBUM ;");
604 query.
prepare(
"INSERT INTO music_albums (artist_id, album_name, compilation, year) "
605 "VALUES (:COMP_ARTIST_ID, :ALBUM, :COMPILATION, :YEAR);");
630 "WHERE genre = :GENRE ;");
643 query.
prepare(
"INSERT INTO music_genres (genre) VALUES (:GENRE);");
695 strQuery =
"INSERT INTO music_songs ( directory_id,"
696 " artist_id, album_id, name, genre_id,"
697 " year, track, length, filename,"
698 " rating, format, date_entered, date_modified,"
699 " numplays, track_count, disc_number, disc_count,"
703 " :ARTIST, :ALBUM, :TITLE, :GENRE,"
704 " :YEAR, :TRACKNUM, :LENGTH, :FILENAME,"
705 " :RATING, :FORMAT, :DATE_ADD, :DATE_MOD,"
706 " :PLAYCOUNT,:TRACKCOUNT, :DISC_NUMBER, :DISC_COUNT,"
707 " :SIZE, :HOSTNAME );";
711 strQuery =
"UPDATE music_songs SET"
712 " directory_id = :DIRECTORY"
713 ", artist_id = :ARTIST"
714 ", album_id = :ALBUM"
716 ", genre_id = :GENRE"
718 ", track = :TRACKNUM"
720 ", filename = :FILENAME"
723 ", date_modified = :DATE_MOD "
724 ", numplays = :PLAYCOUNT "
725 ", track_count = :TRACKCOUNT "
726 ", disc_number = :DISC_NUMBER "
727 ", disc_count = :DISC_COUNT "
729 ", hostname = :HOSTNAME "
730 "WHERE song_id= :ID ;";
733 QString sqlfilename =
m_filename.section(
'/', -1);
765 MythDB::DBError(
"MusicMetadata::dumpToDatabase - updating music_songs",
776 query.
prepare(
"UPDATE music_albums SET album_name = :ALBUM_NAME, "
777 "artist_id = :COMP_ARTIST_ID, compilation = :COMPILATION, "
779 "WHERE music_albums.album_id = :ALBUMID");
865 m_artist = tr(
"Unknown Artist",
"Default artist if no artist");
876 m_album = tr(
"Unknown Album",
"Default album if no album");
883 m_genre = tr(
"Unknown Genre",
"Default genre if no genre");
905 QString format_artist;
906 QString format_title;
1002 if (!mythUrl.isEmpty())
1008 QHostAddress(url.host()).isNull())
1018 LOG(VB_GENERAL, LOG_ERR, QString(
"MusicMetadata: Asked to get the filename for a track but no file found: %1")
1040 if (field ==
"artist")
1042 else if (field ==
"compilation_artist")
1044 else if (field ==
"album")
1046 else if (field ==
"title")
1048 else if (field ==
"genre")
1050 else if (field ==
"filename")
1052 else if (field ==
"year")
1054 else if (field ==
"tracknum")
1056 else if (field ==
"trackcount")
1058 else if (field ==
"discnum")
1060 else if (field ==
"disccount")
1062 else if (field ==
"length")
1064 else if (field ==
"compilation")
1068 LOG(VB_GENERAL, LOG_ERR, QString(
"Something asked me to set data "
1069 "for a field called %1").
arg(field));
1076 if (field ==
"artist")
1078 else if (field ==
"album")
1080 else if (field ==
"title")
1082 else if (field ==
"genre")
1086 LOG(VB_GENERAL, LOG_ERR, QString(
"Something asked me to return data "
1087 "about a field called %1").
arg(field));
1095 metadataMap[
prefix +
"songid"] = QString::number(
m_id);
1124 metadataMap[
prefix +
"lastplayed"] =
1129 metadataMap[
prefix +
"lastplayed"] = tr(
"Never Played");
1138 QString tmpSize = locale.toString(
m_fileSize *
1139 (1.0 / (1024.0 * 1024.0)),
'f', 2);
1140 metadataMap[
prefix +
"filesize"] = tmpSize;
1159 metadataMap[
prefix +
"url"] = url.toString(QUrl::RemoveUserInfo);
1211 for (
auto *art : qAsConst(albumart))
1213 art->m_filename = QString(
"%1-%2").arg(
m_id).arg(art->m_filename);
1222 QStringList searchList;
1226 if (
"artist" == field)
1228 query.
prepare(
"SELECT artist_name FROM music_artists ORDER BY artist_name;");
1230 else if (
"compilation_artist" == field)
1232 query.
prepare(
"SELECT DISTINCT artist_name FROM music_artists, music_albums where "
1233 "music_albums.artist_id=music_artists.artist_id ORDER BY artist_name");
1235 else if (
"album" == field)
1237 query.
prepare(
"SELECT album_name FROM music_albums ORDER BY album_name;");
1239 else if (
"title" == field)
1241 query.
prepare(
"SELECT name FROM music_songs ORDER BY name;");
1243 else if (
"genre" == field)
1245 query.
prepare(
"SELECT genre FROM music_genres ORDER BY genre;");
1282 if (!res.isEmpty() && albumart_image)
1288 QString path =
GetConfDir() +
"/MythMusic/AlbumArt/";
1290 QString
filename = QString(
"%1-%2.%3").arg(
m_id).arg(
"front").arg(fi.suffix());
1294 if (!QFile::exists(albumart_image->
m_filename))
1311 if (url.path().isEmpty() || url.host().isEmpty() || url.userName().isEmpty())
1323 QStringList paramList;
1324 paramList.append(QString(
"--songid='%1'").
arg(
ID()));
1325 paramList.append(QString(
"--imagetype='%1'").
arg(albumart_image->
m_imageType));
1327 QString command =
"mythutil --extractimage " + paramList.join(
" ");
1337 slist <<
"MUSIC_TAG_GETIMAGE"
1339 << QString::number(
ID())
1398 LOG(VB_FILE, LOG_INFO, QString(
"MusicMetadata::getTagger - creating tagger for %1").
arg(
filename));
1402 LOG(VB_GENERAL, LOG_ERR, QString(
"MusicMetadata::getTagger - failed to find %1 on the local filesystem").
arg(
Filename(
false)));
1425 while (!m_allMusic.empty())
1427 delete m_allMusic.back();
1428 m_allMusic.pop_back();
1431 while (!m_cdData.empty())
1433 delete m_cdData.back();
1434 m_cdData.pop_back();
1437 m_metadataLoader->wait();
1438 delete m_metadataLoader;
1447 if (m_metadataLoader->isFinished())
1452 m_metadataLoader->wait();
1471 m_doneLoading =
false;
1473 if (m_metadataLoader)
1476 delete m_metadataLoader;
1480 m_metadataLoader->start();
1492 m_doneLoading =
false;
1494 QString aquery =
"SELECT music_songs.song_id, music_artists.artist_id, music_artists.artist_name, "
1495 "music_comp_artists.artist_name AS compilation_artist, "
1496 "music_albums.album_id, music_albums.album_name, music_songs.name, music_genres.genre, music_songs.year, "
1497 "music_songs.track, music_songs.length, music_songs.directory_id, "
1498 "CONCAT_WS('/', music_directories.path, music_songs.filename) AS filename, "
1499 "music_songs.rating, music_songs.numplays, music_songs.lastplay, music_songs.date_entered, "
1500 "music_albums.compilation, music_songs.format, music_songs.track_count, "
1501 "music_songs.size, music_songs.hostname, music_songs.disc_number, music_songs.disc_count "
1503 "LEFT JOIN music_directories ON music_songs.directory_id=music_directories.directory_id "
1504 "LEFT JOIN music_artists ON music_songs.artist_id=music_artists.artist_id "
1505 "LEFT JOIN music_albums ON music_songs.album_id=music_albums.album_id "
1506 "LEFT JOIN music_artists AS music_comp_artists ON music_albums.artist_id=music_comp_artists.artist_id "
1507 "LEFT JOIN music_genres ON music_songs.genre_id=music_genres.genre_id "
1508 "ORDER BY music_songs.song_id;";
1516 QList<MusicMetadata::IdType> idList;
1544 dbMeta->setDirectoryId(
query.
value(11).toInt());
1546 dbMeta->setCompilationArtistId(
query.
value(3).toInt());
1548 dbMeta->setTrackCount(
query.
value(19).toInt());
1549 dbMeta->setFileSize(
query.
value(20).toULongLong());
1550 dbMeta->setHostname(
query.
value(21).toString());
1551 dbMeta->setDiscNumber(
query.
value(22).toInt());
1552 dbMeta->setDiscCount(
query.
value(23).toInt());
1554 if (!m_musicMap.contains(
id))
1559 m_allMusic.append(dbMeta);
1561 m_musicMap[id] = dbMeta;
1570 if (cacheMeta && !cacheMeta->
compare(dbMeta))
1584 m_playCountMin = m_playCountMax =
query.
value(13).toInt();
1585 m_lastPlayMin = m_lastPlayMax =
query.
value(14).toDateTime().toSecsSinceEpoch();
1590 qint64 lastPlay =
query.
value(14).toDateTime().toSecsSinceEpoch();
1592 m_playCountMin = std::min(playCount, m_playCountMin);
1593 m_playCountMax = std::max(playCount, m_playCountMax);
1594 m_lastPlayMin = std::min(lastPlay, m_lastPlayMin);
1595 m_lastPlayMax = std::max(lastPlay, m_lastPlayMax);
1602 LOG(VB_GENERAL, LOG_ERR,
"MythMusic hasn't found any tracks!");
1606 QList<MusicMetadata::IdType> deleteList;
1607 for (
const auto *track : qAsConst(m_allMusic))
1609 if (!idList.contains(track->ID()))
1611 deleteList.append(track->ID());
1616 for (
uint id : deleteList)
1619 m_allMusic.removeAll(mdata);
1620 m_musicMap.remove(
id);
1626 LOG(VB_GENERAL, LOG_DEBUG, QString(
"AllMusic::resync sending MUSIC_RESYNC_FINISHED added: %1, removed: %2, changed: %3")
1630 m_doneLoading =
true;
1635 if (m_musicMap.contains(an_id))
1636 return m_musicMap[an_id];
1643 return m_musicMap.contains(an_id);
1653 *mdata = *the_track;
1663 for (
auto *item : qAsConst(m_allMusic))
1665 if (item->hasChanged())
1673 while (!m_cdData.empty())
1676 if (m_musicMap.contains(mdata->
ID()))
1677 m_musicMap.remove(mdata->
ID());
1679 delete m_cdData.back();
1680 m_cdData.pop_back();
1683 m_cdTitle = tr(
"CD -- none");
1689 mdata->setID(m_cdData.count() + 1);
1690 mdata->setRepo(
RT_CD);
1691 m_cdData.append(mdata);
1692 m_musicMap[mdata->ID()] = mdata;
1697 if (m_cdData.count() < 1)
1700 return m_cdData.last()->FormatTitle() == the_track->
FormatTitle();
1705 for (
auto *anit : qAsConst(m_cdData))
1707 if (anit->Track() == the_track)
1725 while (!m_streamList.empty())
1727 delete m_streamList.back();
1728 m_streamList.pop_back();
1734 for (
int x = 0; x < m_streamList.count(); x++)
1736 if (m_streamList.at(x)->ID() == an_id)
1745 for (
int x = 0; x < m_streamList.count(); x++)
1747 if (m_streamList.at(x)->ID() == an_id)
1748 return m_streamList.at(x);
1756 while (!m_streamList.empty())
1758 delete m_streamList.back();
1759 m_streamList.pop_back();
1762 QString aquery =
"SELECT intid, broadcaster, channel, description, url1, url2, url3, url4, url5,"
1763 "logourl, genre, metaformat, country, language, format "
1764 "FROM music_radios "
1765 "ORDER BY broadcaster,channel;";
1794 m_streamList.append(mdata);
1799 LOG(VB_GENERAL, LOG_WARNING,
"MythMusic hasn't found any radio streams!");
1807 query.
prepare(
"INSERT INTO music_radios (broadcaster, channel, description, "
1808 "url1, url2, url3, url4, url5, "
1809 "logourl, genre, country, language, format, metaformat) "
1810 "VALUES (:BROADCASTER, :CHANNEL, :DESCRIPTION, :URL1, :URL2, :URL3, :URL4, :URL5, "
1811 ":LOGOURL, :GENRE, :COUNTRY, :LANGUAGE, :FORMAT, :METAFORMAT);");
1844 query.
prepare(
"DELETE FROM music_radios WHERE intid = :ID");
1861 query.
prepare(
"UPDATE music_radios set broadcaster = :BROADCASTER, channel = :CHANNEL, description = :DESCRIPTION, "
1862 "url1 = :URL1, url2 = :URL2, url3 = :URL3, url4 = :URL4, url5 = :URL5, "
1863 "logourl = :LOGOURL, genre = :GENRE, country = :COUNTRY, language = :LANGUAGE, "
1864 "format = :FORMAT, metaformat = :METAFORMAT "
1865 "WHERE intid = :ID");
1894 : m_parent(metadata)
1927 query.
prepare(
"SELECT logourl FROM music_radios WHERE url1 = :URL;");
1937 image->m_filename = logoUrl;
1939 image->m_embedded =
false;
1940 image->m_hostname =
"";
1951 QString
dir = fi.path();
1954 query.
prepare(
"SELECT albumart_id, CONCAT_WS('/', music_directories.path, "
1955 "music_albumart.filename), music_albumart.filename, music_albumart.imagetype, "
1956 "music_albumart.embedded, music_albumart.hostname "
1957 "FROM music_albumart "
1958 "LEFT JOIN music_directories ON "
1959 "music_directories.directory_id = music_albumart.directory_id "
1960 "WHERE music_directories.path = :DIR "
1961 "OR song_id = :SONGID "
1962 "ORDER BY music_albumart.imagetype;");
1970 bool embedded = (
query.
value(4).toInt() == 1);
1977 if (url.scheme() ==
"myth")
1980 QString(
"AlbumArt/") +
query.
value(1).toString(),
1985 image->m_filename =
query.
value(1).toString();
1990 if (url.scheme() ==
"myth")
1998 image->m_filename =
query.
value(1).toString();
2003 image->m_embedded = embedded;
2004 image->m_hostname =
query.
value(5).toString();
2012 if (
findIcon(
"artist", artist) != QString())
2016 image->m_filename =
findIcon(
"artist", artist);
2018 image->m_embedded =
false;
2029 popupStack,
"scanbusydialog");
2041 QStringList strList;
2042 strList <<
"MUSIC_FIND_ALBUMART"
2048 scanThread->start();
2050 while (scanThread->isRunning())
2052 QCoreApplication::processEvents();
2056 strList = scanThread->getResult();
2069 for (
int x = 2; x < strList.count(); x += 6)
2072 image->
m_id = strList[x].toInt();
2073 image->m_imageType = (
ImageType) strList[x + 1].toInt();
2074 image->m_embedded = (strList[x + 2].toInt() == 1);
2075 image->m_description = strList[x + 3];
2077 if (image->m_embedded)
2080 QString(
"AlbumArt/") + strList[x + 4],
2090 image->m_hostname = strList[x + 5];
2092 LOG(VB_FILE, LOG_INFO,
"AlbumArtImages::scanForImages found image");
2093 LOG(VB_FILE, LOG_INFO, QString(
"ID: %1").
arg(image->m_id));
2094 LOG(VB_FILE, LOG_INFO, QString(
"ImageType: %1").
arg(image->m_imageType));
2095 LOG(VB_FILE, LOG_INFO, QString(
"Embedded: %1").
arg(image->m_embedded));
2096 LOG(VB_FILE, LOG_INFO, QString(
"Description: %1").
arg(image->m_description));
2097 LOG(VB_FILE, LOG_INFO, QString(
"Filename: %1").
arg(image->m_filename));
2098 LOG(VB_FILE, LOG_INFO, QString(
"Hostname: %1").
arg(image->m_hostname));
2099 LOG(VB_FILE, LOG_INFO,
"-------------------------------");
2111 if (item->m_imageType ==
type)
2122 if (item->m_id == imageID)
2134 paths += item->m_filename;
2151 static const std::array<const std::string,6> s_typeStrings {
2152 QT_TR_NOOP(
"Unknown"),
2153 QT_TR_NOOP(
"Front Cover"),
2154 QT_TR_NOOP(
"Back Cover"),
2156 QT_TR_NOOP(
"Inlay"),
2157 QT_TR_NOOP(
"Artist"),
2160 return QCoreApplication::translate(
"AlbumArtImages",
2161 s_typeStrings[
type].c_str());
2168 static const std::array<const std::string,6> s_filenameStrings {
2169 QT_TR_NOOP(
"unknown"),
2170 QT_TR_NOOP(
"front"),
2173 QT_TR_NOOP(
"inlay"),
2174 QT_TR_NOOP(
"artist")
2177 return QCoreApplication::translate(
"AlbumArtImages",
2178 s_filenameStrings[
type].c_str());
2186 if (
filename.contains(
"front", Qt::CaseInsensitive) ||
2187 filename.contains(tr(
"front"), Qt::CaseInsensitive) ||
2188 filename.contains(
"cover", Qt::CaseInsensitive) ||
2189 filename.contains(tr(
"cover"), Qt::CaseInsensitive))
2191 else if (
filename.contains(
"back", Qt::CaseInsensitive) ||
2192 filename.contains(tr(
"back"), Qt::CaseInsensitive))
2194 else if (
filename.contains(
"inlay", Qt::CaseInsensitive) ||
2195 filename.contains(tr(
"inlay"), Qt::CaseInsensitive))
2197 else if (
filename.contains(
"cd", Qt::CaseInsensitive) ||
2198 filename.contains(tr(
"cd"), Qt::CaseInsensitive))
2209 if (name.toLower() ==
"front")
2211 else if (name.toLower() ==
"back")
2213 else if (name.toLower() ==
"inlay")
2215 else if (name.toLower() ==
"cd")
2217 else if (name.toLower() ==
"artist")
2219 else if (name.toLower() ==
"unknown")
2264 if (trackID == 0 || directoryID == -1)
2266 LOG(VB_GENERAL, LOG_ERR,
"AlbumArtImages: Asked to save to the DB but "
2267 "have invalid songid or directoryid");
2275 "WHERE song_id = :SONGID "
2276 "OR (embedded = 0 AND directory_id = :DIRECTORYID)");
2284 "deleting existing albumart",
query);
2294 if (image->m_id > 0)
2297 query.
prepare(
"INSERT INTO music_albumart ( albumart_id, "
2298 "filename, imagetype, song_id, directory_id, embedded, hostname ) "
2299 "VALUES ( :ID, :FILENAME, :TYPE, :SONGID, :DIRECTORYID, :EMBED, :HOSTNAME );");
2304 query.
prepare(
"INSERT INTO music_albumart ( filename, "
2305 "imagetype, song_id, directory_id, embedded, hostname ) VALUES ( "
2306 ":FILENAME, :TYPE, :SONGID, :DIRECTORYID, :EMBED, :HOSTNAME );");
2309 QFileInfo fi(image->m_filename);
2314 query.
bindValue(
":DIRECTORYID", image->m_embedded ? 0 : directoryID);
2321 "add/update music_albumart",
query);
2325 if (image->m_id <= 0)
QString MythFormatTimeMs(int msecs, const QString &fmt)
Format a milliseconds time value.
bool isActive(void) const
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
QSqlQuery wrapper that fetches a DB connection from the connection pool.
void SendMessage(const QString &message)
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
void bindValueNoNull(const QString &placeholder, const QVariant &val)
Add a single binding, taking care not to set a NULL value.
bool isValidID(MusicMetadata::IdType an_id)
QString GetMasterHostName(void)
void updateStream(MusicMetadata *mdata)
void addStream(MusicMetadata *mdata)
std::shared_ptr< MythSortHelper > getMythSortHelper(void)
Get a pointer to the MythSortHelper singleton.
@ kMSDontBlockInputDevs
avoid blocking LIRC & Joystick Menu
bool SendReceiveStringList(QStringList &strlist, bool quickTimeout=false, bool block=true)
Send a message to the backend and wait for a response.
QDateTime as_utc(const QDateTime &old_dt)
Returns copy of QDateTime with TimeSpec set to UTC.
bool isValidID(int an_id)
static bool Exists(const QString &url, struct stat *fileinfo)
AlbumArtList * getImageList(void)
QString FindFile(const QString &filename)
MusicMetadata * getMetadata(MusicMetadata::IdType an_id)
static ImageType getImageTypeFromName(const QString &name)
QVariant lastInsertId()
Return the id of the last inserted row.
bool startLoading(void)
Start loading metadata.
QVariant value(int i) const
arg(title).arg(filename).arg(doDelete))
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
static ImageType guessImageType(const QString &filename)
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
AlbumArtImage * getImage(ImageType type)
MusicMetadata * getCDMetadata(int m_the_track)
QHash< QString, QString > InfoMap
bool checkCDTrack(MusicMetadata *the_track)
bool IsMasterBackend(void)
is this the actual MBE process
bool ClearSetting(const QString &key)
static QString GenMythURL(const QString &host=QString(), int port=0, QString path=QString(), const QString &storageGroup=QString())
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
static void DBError(const QString &where, const MSqlQuery &query)
bool updateMetadata(int an_id, MusicMetadata *the_track)
AlbumArtImage * getImageAt(uint index)
static QString getTypeFilename(ImageType type)
void addCDTrack(const MusicMetadata &the_track)
void removeStream(MusicMetadata *mdata)
static QString FindFile(const QString &filename, const QString &host, const QString &storageGroup, bool useRegex=false, bool allowFallback=false)
Search all BE's for a file in the give storage group.
static QString getTypeName(ImageType type)
MusicMetadata * getMetadata(int an_id)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
AlbumArtImage * getImageByID(int imageID)
@ kMSAutoCleanup
automatically delete if backgrounded
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
void resync()
resync our cache with the database
@ kMSRunBackground
run child in the background
@ kSimplify
Do Today/Yesterday/Tomorrow transform.
AlbumArtImages(MusicMetadata *metadata, bool loadFromDB=true)
QDateTime lastUpdate(GrabberScript *script)
@ kAddYear
Add year to string if not included.
@ kMSProcessEvents
process events while waiting
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
void save()
Check each MusicMetadata entry and save those that have changed (ratings, etc.)
MythMainWindow * GetMythMainWindow(void)
MythScreenStack * GetStack(const QString &Stackname)
@ kDateFull
Default local time.
int numRowsAffected() const
QString GetHostName(void)
QByteArray gzipUncompress(const QByteArray &data)
QDateTime GetLastModified(const QString &url)
Gets the Last Modified timestamp for a URI.
@ kMSDontDisableDrawing
avoid disabling UI drawing
void addImage(const AlbumArtImage *newImage)
void dumpToDatabase(void)
saves or updates the image details in the DB
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
MSqlQuery query(MSqlQuery::InitCon())
META_PUBLIC QString findIcon(const QString &type, const QString &name, bool ignoreCache=false)
find an image for a artist or genre
bool SaveSettingOnHost(const QString &key, const QString &newValue, const QString &host)
QStringList getImageFilenames(void) const
static pid_list_t::iterator find(const PIDInfoMap &map, pid_list_t &list, pid_list_t::iterator begin, pid_list_t::iterator end, bool find_open)
QString GetSetting(const QString &key, const QString &defaultval="")
MythDownloadManager * GetMythDownloadManager(void)
Gets the pointer to the MythDownloadManager singleton.
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
static MythSystem * Create(const QStringList &args, uint flags=kMSNone, const QString &startPath=QString(), Priority cpuPriority=kInheritPriority, Priority diskPriority=kInheritPriority)