MythTV  master
musicmetadata.h
Go to the documentation of this file.
1 #ifndef MUSICMETADATA_H_
2 #define MUSICMETADATA_H_
3 
4 // C/C++
5 #include <cstdint>
6 
7 // qt
8 #include <QStringList>
9 #include <QMap>
10 #include <QDateTime>
11 #include <QImage>
12 #include <QMetaType>
13 #include <QCoreApplication>
14 
15 // mythtv
16 #include "mythtypes.h"
17 #include "mythmetaexp.h"
18 #include "mthread.h"
19 #include "mythcorecontext.h"
20 
21 class AllMusic;
22 class AlbumArtImages;
23 class LyricsData;
24 class MetaIO;
25 
27 {
35 };
36 
38 {
39  public:
40  AlbumArtImage(void) :
41  id(0), filename(""), hostname(""), imageType(IT_UNKNOWN),
42  description(""), embedded(false) {}
44  id(image->id), filename(image->filename), hostname(image->hostname), imageType(image->imageType),
45  description(image->description), embedded(image->embedded) {}
46  int id;
47  QString filename;
48  QString hostname;
50  QString description;
51  bool embedded;
52 };
53 
54 typedef QList<AlbumArtImage*> AlbumArtList;
55 
57 {
59  RT_CD = 1,
61 };
62 
63 #define METADATA_BITS_FOR_REPO 8
64 #define METADATA_REPO_SHIFT 24
65 #define METADATA_REPO_MASK 0xff000000
66 #define METADATA_ID_MASK 0x00ffffff
67 
68 #define ID_TO_ID(x) x & METADATA_ID_MASK;
69 #define ID_TO_REPO(x) x >> METADATA_REPO_SHIFT
70 
71 #define METADATA_INVALID_FILENAME "**NOT FOUND**"
72 
73 #define STREAMUPDATEURL "https://services.mythtv.org/music/data/?data=streams"
74 #define STREAMURLCOUNT 5
75 
76 typedef QString UrlList[STREAMURLCOUNT];
77 
79 {
80  Q_DECLARE_TR_FUNCTIONS(MusicMetadata);
81 
82  public:
83 
84  typedef uint32_t IdType;
85 
86  MusicMetadata(QString lfilename = "", QString lartist = "", QString lcompilation_artist = "",
87  QString lalbum = "", QString ltitle = "", QString lgenre = "",
88  int lyear = 0, int ltracknum = 0, int llength = 0, int lid = 0,
89  int lrating = 0, int lplaycount = 0, QDateTime llastplay = QDateTime(),
90  QDateTime ldateadded = QDateTime(), bool lcompilation = false, QString lformat = "")
91  : m_artist(lartist),
92  m_compilation_artist(lcompilation_artist),
93  m_album(lalbum),
94  m_title(ltitle),
95  m_formattedartist(""),
96  m_formattedtitle(""),
97  m_genre(lgenre),
98  m_format(lformat),
99  m_year(lyear),
100  m_tracknum(ltracknum),
101  m_trackCount(0),
102  m_discnum(0),
103  m_disccount(0),
104  m_length(llength),
105  m_rating(lrating),
106  m_directoryid(-1),
107  m_artistid(-1),
108  m_compartistid(-1),
109  m_albumid(-1),
110  m_genreid(-1),
111  m_lastplay(llastplay),
112  m_templastplay(QDateTime()),
113  m_dateadded(ldateadded),
114  m_playcount(lplaycount),
115  m_tempplaycount(0),
116  m_compilation(lcompilation),
117  m_albumArt(nullptr),
118  m_lyricsData(nullptr),
119  m_id(lid),
120  m_filename(lfilename),
121  m_fileSize(0),
122  m_changed(false),
123  m_broadcaster(""),
124  m_channel(""),
125  m_description(""),
126  m_logoUrl(""),
127  m_metaFormat(""),
128  m_country(""),
129  m_language("")
130 
131  {
132  checkEmptyFields();
133  ensureSortFields();
134  }
135 
136  MusicMetadata(int lid, QString lbroadcaster, QString lchannel, QString ldescription, UrlList lurls, QString llogourl,
137  QString lgenre, QString lmetaformat, QString lcountry, QString llanguage, QString lformat);
138 
139  ~MusicMetadata();
140 
142  {
143  *this = other;
144  m_changed = false;
145  }
146 
147  MusicMetadata& operator=(const MusicMetadata &other);
148 
149  QString Artist() const { return m_artist; }
150  QString ArtistSort() const { return m_artist_sort; }
151  void setArtist(const QString &lartist,
152  const QString &lartist_sort = nullptr)
153  {
154  m_artist = lartist;
155  m_artist_sort = lartist_sort;
156  m_formattedartist.clear(); m_formattedtitle.clear();
157  ensureSortFields();
158  }
159 
160  QString CompilationArtist() const { return m_compilation_artist; }
161  QString CompilationArtistSort() const { return m_compilation_artist_sort; }
162  void setCompilationArtist(const QString &lcompilation_artist,
163  const QString &lcompilation_artist_sort = nullptr)
164  {
165  m_compilation_artist = lcompilation_artist;
166  m_compilation_artist_sort = lcompilation_artist_sort;
167  m_formattedartist.clear(); m_formattedtitle.clear();
168  ensureSortFields();
169  }
170 
171  QString Album() const { return m_album; }
172  QString AlbumSort() const { return m_album_sort; }
173  void setAlbum(const QString &lalbum,
174  const QString &lalbum_sort = nullptr)
175  {
176  m_album = lalbum;
177  m_album_sort = lalbum_sort;
178  m_formattedartist.clear(); m_formattedtitle.clear();
179  ensureSortFields();
180  }
181 
182  QString Title() const { return m_title; }
183  QString TitleSort() const { return m_title_sort; }
184  void setTitle(const QString &ltitle,
185  const QString &ltitle_sort = nullptr)
186  {
187  m_title = ltitle;
188  m_title_sort = ltitle_sort;
189  ensureSortFields();
190  }
191 
192  QString FormatArtist();
193  QString FormatTitle();
194 
195  QString Genre() const { return m_genre; }
196  void setGenre(const QString &lgenre) { m_genre = lgenre; }
197 
198  void setDirectoryId(int ldirectoryid) { m_directoryid = ldirectoryid; }
199  int getDirectoryId();
200 
201  void setArtistId(int lartistid) { m_artistid = lartistid; }
202  int getArtistId();
203 
204  void setAlbumId(int lalbumid) { m_albumid = lalbumid; }
205  int getAlbumId();
206 
207  void setGenreId(int lgenreid) { m_genreid = lgenreid; }
208  int getGenreId();
209 
210  int Year() const { return m_year; }
211  void setYear(int lyear) { m_year = lyear; }
212 
213  int Track() const { return m_tracknum; }
214  void setTrack(int ltrack) { m_tracknum = ltrack; }
215 
216  int GetTrackCount() const { return m_trackCount; }
217  void setTrackCount(int ltrackcount) { m_trackCount = ltrackcount; }
218 
219  int Length() const { return m_length; }
220  void setLength(int llength) { m_length = llength; }
221 
222  int DiscNumber() const {return m_discnum;}
223  void setDiscNumber(int discnum) { m_discnum = discnum; }
224 
225  int DiscCount() const {return m_disccount;}
226  void setDiscCount(int disccount) { m_disccount = disccount; }
227 
228  int Playcount() const { return m_playcount; }
229  void setPlaycount(int lplaycount) { m_playcount = lplaycount; }
230 
231  IdType ID() const { return m_id; }
232  void setID(IdType lid) { m_id = lid; }
233  void setRepo(RepoType repo) { m_id = (m_id & METADATA_ID_MASK) | (repo << METADATA_REPO_SHIFT); }
234 
235  bool isCDTrack(void) const { return ID_TO_REPO(m_id) == RT_CD; }
236  bool isDBTrack(void) const { return ID_TO_REPO(m_id) == RT_Database; }
237  bool isRadio(void) const { return ID_TO_REPO(m_id) == RT_Radio; }
238 
239  QString Filename(bool find = true);
240  void setFilename(const QString &lfilename);
241  QString getLocalFilename(void);
242 
243  QString Hostname(void) { return m_hostname; }
244  void setHostname(const QString &host) { m_hostname = host; }
245 
246  uint64_t FileSize() const { return m_fileSize; }
247  void setFileSize(uint64_t lfilesize) { m_fileSize = lfilesize; }
248 
249  QString Format() const { return m_format; }
250  void setFormat(const QString &lformat) { m_format = lformat; }
251 
252  int Rating() const { return m_rating; }
253  void decRating();
254  void incRating();
255  void setRating(int lrating) { m_rating = lrating; }
256 
257  QDateTime LastPlay() const { return m_lastplay; }
258  void setLastPlay();
259  void setLastPlay(QDateTime lastPlay);
260 
261  int PlayCount() const { return m_playcount; }
262  void incPlayCount();
263 
264  // track is part of a compilation album
265  bool Compilation() const { return m_compilation; }
266  void setCompilation(bool state)
267  {
268  m_compilation = state;
269  m_formattedartist.clear();
270  m_formattedtitle.clear();
271  }
272  bool determineIfCompilation(bool cd = false);
273 
274  // for radio streams
275  void setBroadcaster(const QString &broadcaster) { m_broadcaster = broadcaster; }
276  QString Broadcaster(void) { return m_broadcaster; }
277 
278  void setChannel(const QString &channel) { m_channel = channel; }
279  QString Channel(void) { return m_channel; }
280 
281  void setDescription(const QString &description) { m_description = description; }
282  QString Description(void) { return m_description; }
283 
284  void setUrl(const QString &url, uint index = 0);
285  QString Url(uint index = 0);
286 
287  void setLogoUrl(const QString &logourl) { m_logoUrl = logourl; }
288  QString LogoUrl(void) { return m_logoUrl; }
289 
290  void setMetadataFormat(const QString &metaformat) { m_metaFormat = metaformat; }
291  QString MetadataFormat(void) { return m_metaFormat; }
292 
293  void setCountry(const QString &country) { m_country = country; }
294  QString Country(void) { return m_country; }
295 
296  void setLanguage(const QString &language) { m_language = language; }
297  QString Language(void) { return m_language; }
298 
299  void setEmbeddedAlbumArt(AlbumArtList &albumart);
300 
301  void reloadMetadata(void);
302  void dumpToDatabase(void);
303  void setField(const QString &field, const QString &data);
304  void getField(const QString& field, QString *data);
305  void toMap(InfoMap &metadataMap, const QString &prefix = "");
306 
307  void persist(void);
308 
309  bool hasChanged(void) const { return m_changed; }
310 
311  bool compare(MusicMetadata *mdata) const;
312 
313  // static functions
314  static MusicMetadata *createFromFilename(const QString &filename);
315  static MusicMetadata *createFromID(int trackid);
316  static void setArtistAndTrackFormats();
317  static QStringList fillFieldList(QString field);
318  static bool updateStreamList(void);
319 
320  // this looks for any image available - preferring a front cover if available
321  QString getAlbumArtFile(void);
322  // this looks only for the given image type
323  QString getAlbumArtFile(ImageType type);
324 
325  AlbumArtImages *getAlbumArtImages(void);
326  void reloadAlbumArtImages(void);
327 
328  LyricsData *getLyricsData(void);
329 
330  MetaIO *getTagger(void);
331 
332  private:
333  void setCompilationFormatting(bool cd = false);
334  QString formatReplaceSymbols(const QString &format);
335  void checkEmptyFields(void);
336  void ensureSortFields(void);
337  void saveHostname(void);
338 
339  QString m_artist;
340  QString m_artist_sort;
343  QString m_album;
344  QString m_album_sort;
345  QString m_title;
346  QString m_title_sort;
349  QString m_genre;
350  QString m_genre_sort;
351  QString m_format;
352  int m_year;
357  int m_length;
358  int m_rating;
364  QDateTime m_lastplay;
365  QDateTime m_templastplay;
366  QDateTime m_dateadded;
370 
372 
374 
376  QString m_filename; // file name as stored in the DB
377  QString m_hostname; // host where file is located as stored in the DB
378  QString m_actualFilename; // actual URL of the file if found
379  uint64_t m_fileSize;
380  bool m_changed;
381 
382  // radio stream stuff
383  QString m_broadcaster;
384  QString m_channel;
385  QString m_description;
387  QString m_logoUrl;
388  QString m_metaFormat;
389  QString m_country;
390  QString m_language;
391 
392  // Various formatting strings
393  static QString m_formatnormalfileartist;
394  static QString m_formatnormalfiletrack;
395  static QString m_formatnormalcdartist;
396  static QString m_formatnormalcdtrack;
397 
402 };
403 
406 
409 
413 
414 //---------------------------------------------------------------------------
415 
417 {
418 
419  public:
420 
421  explicit MetadataLoadingThread(AllMusic *parent_ptr);
422  void run() override; // MThread
423 
424  private:
425 
427 };
428 
429 //---------------------------------------------------------------------------
430 
432 {
433  Q_DECLARE_TR_FUNCTIONS(AllMusic);
434 
435  public:
436 
437  AllMusic(void);
438  ~AllMusic();
439 
440  MusicMetadata* getMetadata(int an_id);
441  bool updateMetadata(int an_id, MusicMetadata *the_track);
442  int count() const { return m_numPcs; }
443  int countLoaded() const { return m_numLoaded; }
444  void save();
445  bool startLoading(void);
446  void resync(); // After a CD rip, for example
447 
448  // cd stuff
449  void clearCDData(void);
450  void addCDTrack(const MusicMetadata &the_track);
451  bool checkCDTrack(MusicMetadata *the_track);
452  MusicMetadata* getCDMetadata(int m_the_track);
453  QString getCDTitle(void) const { return m_cdTitle; }
454  void setCDTitle(const QString &a_title) { m_cdTitle = a_title; }
455  int getCDTrackCount(void) const { return m_cdData.count(); }
456 
457  bool doneLoading() const { return m_done_loading; }
458  bool cleanOutThreads();
459 
460  MetadataPtrList *getAllMetadata(void) { return &m_all_music; }
461  MetadataPtrList *getAllCDMetadata(void) { return &m_cdData; }
462 
463  bool isValidID(int an_id);
464 
465  private:
467 
468  int m_numPcs;
470 
471  typedef QMap<int, MusicMetadata*> MusicMap;
473 
474  // cd stuff
475  MetadataPtrList m_cdData; // More than one cd player?
476  QString m_cdTitle;
477 
480 
483 #if QT_VERSION < QT_VERSION_CHECK(5,8,0)
484  double m_lastplayMin;
485  double m_lastplayMax;
486 #else
489 #endif
490 };
491 
492 typedef QList<MusicMetadata*> StreamList;
493 
495 {
496  public:
497 
498  AllStream(void);
499  ~AllStream();
500 
501  void loadStreams(void);
502 
503  bool isValidID(MusicMetadata::IdType an_id);
504 
505  MusicMetadata* getMetadata(MusicMetadata::IdType an_id);
506 
507  StreamList *getStreams(void) { return &m_streamList; }
508 
509  void addStream(MusicMetadata *mdata);
510  void removeStream(MusicMetadata *mdata);
511  void updateStream(MusicMetadata *mdata);
512 
513  private:
515 };
516 
517 //----------------------------------------------------------------------------
518 
520 {
521  public:
522  explicit AlbumArtScannerThread(QStringList strList) :
523  MThread("AlbumArtScanner"), m_strList(strList) {}
524 
525  void run() override // MThread
526  {
527  RunProlog();
529  RunEpilog();
530  }
531 
532  QStringList getResult(void) { return m_strList; }
533 
534  private:
535  QStringList m_strList;
536 };
537 
539 {
540  Q_DECLARE_TR_FUNCTIONS(AlbumArtImages);
541 
542  public:
543  AlbumArtImages(MusicMetadata *metadata, bool loadFromDB = true);
544  ~AlbumArtImages();
545 
546  void scanForImages(void);
547  void addImage(const AlbumArtImage &newImage);
548  uint getImageCount() { return m_imageList.size(); }
549  AlbumArtImage *getImage(ImageType type);
550  AlbumArtImage *getImageByID(int imageID);
551  QStringList getImageFilenames(void) const;
552  AlbumArtList *getImageList(void) { return &m_imageList; }
553  AlbumArtImage *getImageAt(uint index);
554 
555  void dumpToDatabase(void);
556 
557  static ImageType guessImageType(const QString &filename);
558  static QString getTypeName(ImageType type);
559  static QString getTypeFilename(ImageType type);
560  static ImageType getImageTypeFromName(const QString &name);
561 
562  private:
563  void findImages(void);
564 
567 };
568 
570 
571 #endif
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
Definition: mthread.cpp:216
MusicMap music_map
#define ID_TO_REPO(x)
Definition: musicmetadata.h:69
void setDiscCount(int disccount)
bool hasChanged(void) const
int m_numLoaded
uint64_t m_fileSize
int getCDTrackCount(void) const
MusicMetadata(QString lfilename="", QString lartist="", QString lcompilation_artist="", QString lalbum="", QString ltitle="", QString lgenre="", int lyear=0, int ltracknum=0, int llength=0, int lid=0, int lrating=0, int lplaycount=0, QDateTime llastplay=QDateTime(), QDateTime ldateadded=QDateTime(), bool lcompilation=false, QString lformat="")
Definition: musicmetadata.h:86
QList< MusicMetadata * > StreamList
QMap< int, MusicMetadata * > MusicMap
This is a wrapper around QThread that does several additional things.
Definition: mthread.h:46
ImageType imageType
Definition: musicmetadata.h:49
int DiscNumber() const
void setGenreId(int lgenreid)
void setTrack(int ltrack)
bool isRadio(void) const
void setDirectoryId(int ldirectoryid)
QStringList getResult(void)
uint getImageCount()
void setYear(int lyear)
QString LogoUrl(void)
QDateTime m_lastplay
QString Language(void)
QString Genre() 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 Hostname(void)
int GetTrackCount() const
QString m_actualFilename
void setLength(int llength)
RepoType
Definition: musicmetadata.h:56
QDateTime m_dateadded
static QString m_formatcompilationfileartist
void setBroadcaster(const QString &broadcaster)
void setLanguage(const QString &language)
bool operator!=(MusicMetadata &a, MusicMetadata &b)
static QString m_formatcompilationfiletrack
QList< AlbumArtImage * > AlbumArtList
Definition: musicmetadata.h:54
QString CompilationArtistSort() const
QString filename
Definition: musicmetadata.h:47
void setDiscNumber(int discnum)
QString m_filename
QString ArtistSort() const
QString MetadataFormat(void)
void setCDTitle(const QString &a_title)
int Length() const
uint64_t FileSize() const
unsigned int uint
Definition: compat.h:140
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
MusicMetadata * m_parent
QString Country(void)
void setLogoUrl(const QString &logourl)
qint64 m_lastplayMax
AlbumArtList * getImageList(void)
#define STREAMURLCOUNT
Definition: musicmetadata.h:74
QString AlbumSort() const
QString m_title_sort
int Rating() const
int PlayCount() const
void setHostname(const QString &host)
AlbumArtList m_imageList
static QString m_formatcompilationcdtrack
MusicMetadata(const MusicMetadata &other)
Definition: metaio.h:17
bool isCDTrack(void) const
unsigned char b
Definition: ParseText.cpp:340
void setCompilation(bool state)
QString m_format
QString Artist() const
bool isDBTrack(void) const
int m_playcountMax
static int run(MythMediaDevice *dev=nullptr, bool startRandomShow=false)
bool SendReceiveStringList(QStringList &strlist, bool quickTimeout=false, bool block=true)
Send a message to the backend and wait for a response.
LyricsData * m_lyricsData
VERBOSE_PREAMBLE false
Definition: verbosedefs.h:85
QString Channel(void)
void setArtistId(int lartistid)
QHash< QString, QString > InfoMap
Definition: mythtypes.h:15
QString UrlList[STREAMURLCOUNT]
Definition: musicmetadata.h:76
QString m_language
QString m_metaFormat
#define META_PUBLIC
Definition: mythmetaexp.h:9
void setAlbumId(int lalbumid)
QString m_artist_sort
QString m_logoUrl
QDateTime m_templastplay
StreamList m_streamList
static QString m_formatnormalcdartist
#define METADATA_REPO_SHIFT
Definition: musicmetadata.h:64
AlbumArtImages * m_albumArt
IdType ID() const
void setChannel(const QString &channel)
void setAlbum(const QString &lalbum, const QString &lalbum_sort=nullptr)
void setRating(int lrating)
static QString m_formatcompilationcdartist
QString hostname
Definition: musicmetadata.h:48
int Track() const
AlbumArtScannerThread(QStringList strList)
QString description
Definition: musicmetadata.h:50
void setRepo(RepoType repo)
string hostname
Definition: caa.py:17
QString Album() const
QString m_channel
QString m_hostname
const char * name
Definition: ParseText.cpp:339
AlbumArtImage(void)
Definition: musicmetadata.h:40
int m_playcountMin
StreamList * getStreams(void)
void setFormat(const QString &lformat)
qint64 m_lastplayMin
void setTitle(const QString &ltitle, const QString &ltitle_sort=nullptr)
void setArtist(const QString &lartist, const QString &lartist_sort=nullptr)
QString Format() const
QString m_description
QString m_compilation_artist_sort
AlbumArtImage(AlbumArtImage *image)
Definition: musicmetadata.h:43
QString m_artist
QString TitleSort() const
QList< MusicMetadata * > MetadataPtrList
bool Compilation() const
Q_DECLARE_METATYPE(ImageType)
bool doneLoading() const
int Year() const
QString Description(void)
#define METADATA_ID_MASK
Definition: musicmetadata.h:66
QString m_genre_sort
QString Title() const
void setPlaycount(int lplaycount)
QString m_formattedtitle
void setFileSize(uint64_t lfilesize)
void RunProlog(void)
Sets up a thread, call this if you reimplement run().
Definition: mthread.cpp:203
MetadataPtrList m_cdData
void setMetadataFormat(const QString &metaformat)
QString m_compilation_artist
void setDescription(const QString &description)
static QString m_formatnormalfileartist
bool m_done_loading
QDateTime LastPlay() const
ImageType
Definition: musicmetadata.h:26
QString CompilationArtist() const
QString m_album_sort
int countLoaded() const
QString getCDTitle(void) const
QString m_broadcaster
static QString m_formatnormalfiletrack
bool operator==(MusicMetadata &a, MusicMetadata &b)
void run() override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
QString m_country
int Playcount() const
int DiscCount() const
void setTrackCount(int ltrackcount)
MetadataPtrList * getAllMetadata(void)
QString Broadcaster(void)
void setCompilationArtist(const QString &lcompilation_artist, const QString &lcompilation_artist_sort=nullptr)
int count() const
MetadataPtrList m_all_music
MetadataPtrList * getAllCDMetadata(void)
uint32_t IdType
Definition: musicmetadata.h:84
QString m_cdTitle
QString m_formattedartist
void setID(IdType lid)
void setCountry(const QString &country)
MetadataLoadingThread * m_metadata_loader
static QString m_formatnormalcdtrack
void setGenre(const QString &lgenre)