MythTV  master
playlistcontainer.cpp
Go to the documentation of this file.
1 // MythTV
2 #include <mythcontext.h>
3 #include <mythdb.h>
4 #include <compat.h>
5 #include <mythlogging.h>
6 
7 #include <utility>
8 
9 // mythmusic
10 #include "playlist.h"
11 #include "playlistcontainer.h"
12 
13 
15 {
16  RunProlog();
17  while (!all_music->doneLoading())
18  {
19  msleep(250);
20  }
21  parent->load();
22  RunEpilog();
23 }
24 
25 #define LOC QString("PlaylistContainer: ")
26 #define LOC_WARN QString("PlaylistContainer, Warning: ")
27 #define LOC_ERR QString("PlaylistContainer, Error: ")
28 
30  m_playlistsLoader(new PlaylistLoadingThread(this, all_music)),
31  m_myHost(gCoreContext->GetHostName()),
32 
33  m_ratingWeight( gCoreContext->GetNumSetting("IntelliRatingWeight", 2)),
34  m_playCountWeight(gCoreContext->GetNumSetting("IntelliPlayCountWeight", 2)),
35  m_lastPlayWeight( gCoreContext->GetNumSetting("IntelliLastPlayWeight", 2)),
36  m_randomWeight( gCoreContext->GetNumSetting("IntelliRandomWeight", 2))
37 {
39 }
40 
42 {
44  delete m_playlistsLoader;
45  m_playlistsLoader = nullptr;
46 
47  delete m_activePlaylist;
48  delete m_streamPlaylist;
49  if (m_allPlaylists)
50  {
51  while (!m_allPlaylists->empty())
52  {
53  delete m_allPlaylists->front();
54  m_allPlaylists->pop_front();
55  }
56  delete m_allPlaylists;
57  }
58 }
59 
61  int &lastplay, int &random)
62 {
64  playcount = m_playCountWeight;
65  lastplay = m_lastPlayWeight;
67 }
68 
70 {
71  m_doneLoading = false;
72  m_activePlaylist = new Playlist();
74 
75  m_streamPlaylist = new Playlist();
77 
78  m_allPlaylists = new QList<Playlist*>;
79 
81 
83 
85  query.prepare("SELECT playlist_id FROM music_playlists "
86  "WHERE playlist_name != :DEFAULT"
87  " AND playlist_name != :BACKUP "
88  " AND playlist_name != :STREAM "
89  " AND (hostname = '' OR hostname = :HOST) "
90  "ORDER BY playlist_name;");
91  query.bindValue(":DEFAULT", DEFAULT_PLAYLIST_NAME);
92  query.bindValue(":BACKUP", "backup_playlist_storage");
93  query.bindValue(":STREAM", DEFAULT_STREAMLIST_NAME);
94  query.bindValue(":HOST", m_myHost);
95 
96  if (!query.exec())
97  {
98  MythDB::DBError("Querying playlists", query);
99  }
100  else
101  {
102  while (query.next())
103  {
104  Playlist *temp_playlist = new Playlist();
105  // No, we don't destruct this ...
106  temp_playlist->setParent(this);
107  temp_playlist->loadPlaylistByID(query.value(0).toInt(), m_myHost);
108  m_allPlaylists->push_back(temp_playlist);
109  // ... cause it's sitting on this PtrList
110  }
111  }
112 
113  m_doneLoading = true;
114 }
115 
116 // resync all the playlists after a rescan just in case some tracks were removed
118 {
119  QList<Playlist*>::const_iterator it = m_allPlaylists->begin();
120  for (; it != m_allPlaylists->end(); ++it)
121  {
122  (*it)->resync();
123  }
124 
126 }
127 
129 {
130  // Debugging
132  QList<Playlist*>::const_iterator it = m_allPlaylists->begin();
133  for (; it != m_allPlaylists->end(); ++it)
134  (*it)->describeYourself();
135 }
136 
138 {
139  // return a pointer to a playlist
140  // by id;
141 
142  if (m_activePlaylist->getID() == id)
143  {
144  return m_activePlaylist;
145  }
146 
147  QList<Playlist*>::iterator it = m_allPlaylists->begin();
148  for (; it != m_allPlaylists->end(); ++it)
149  {
150  if ((*it)->getID() == id)
151  return *it;
152  }
153 
154  LOG(VB_GENERAL, LOG_ERR,
155  "getPlaylistName() called with unknown index number");
156  return nullptr;
157 }
158 
160 {
161  // return a pointer to a playlist
162  // by name;
163 
164  QList<Playlist*>::iterator it = m_allPlaylists->begin();
165  for (; it != m_allPlaylists->end(); ++it)
166  {
167  if ((*it)->getName() == name)
168  return *it;
169  }
170 
171  LOG(VB_GENERAL, LOG_ERR, QString("getPlaylistName() called with unknown name: %1").arg(name));
172  return nullptr;
173 }
174 
176 {
177  QList<Playlist*>::const_iterator it = m_allPlaylists->begin();
178  for (; it != m_allPlaylists->end(); ++it)
179  {
180  if ((*it)->hasChanged())
181  (*it)->savePlaylist((*it)->getName(), m_myHost);
182  }
183 
186 }
187 
189 {
190  Playlist *new_list = new Playlist();
191  new_list->setParent(this);
192 
193  // Need to touch the database to get persistent ID
194  new_list->savePlaylist(std::move(name), m_myHost);
195 
196  m_allPlaylists->push_back(new_list);
197 }
198 
200 {
201  Playlist *new_list = new Playlist();
202  new_list->setParent(this);
203 
204  // Need to touch the database to get persistent ID
205  new_list->savePlaylist(std::move(name), m_myHost);
206 
207  m_allPlaylists->push_back(new_list);
208  m_activePlaylist->copyTracks(new_list, false);
209 }
210 
212 {
214  Playlist *copy_from = getPlaylist(index);
215  if (!copy_from)
216  {
217  LOG(VB_GENERAL, LOG_ERR, LOC + "copyToActive() " +
218  QString("Unknown playlist: %1").arg(index));
219  return;
220  }
221  copy_from->copyTracks(m_activePlaylist, true);
222 }
223 
224 void PlaylistContainer::renamePlaylist(int index, QString new_name)
225 {
226  Playlist *list_to_rename = getPlaylist(index);
227  if (list_to_rename)
228  {
229  list_to_rename->setName(std::move(new_name));
230  list_to_rename->changed();
231  }
232 }
233 
235 {
236  Playlist *list_to_kill = getPlaylist(kill_me);
237  if (!list_to_kill)
238  {
239  LOG(VB_GENERAL, LOG_ERR, LOC + "deletePlaylist() " +
240  QString("Unknown playlist: %1").arg(kill_me));
241  return;
242  }
243 
244  list_to_kill->removeAllTracks();
245  m_allPlaylists->removeAll(list_to_kill);
246 
247  MSqlQuery query(MSqlQuery::InitCon());
248  query.prepare("DELETE FROM music_playlists WHERE playlist_id = :ID ;");
249  query.bindValue(":ID", kill_me);
250 
251  if (!query.exec() || query.numRowsAffected() < 1)
252  {
253  MythDB::DBError("playlist delete", query);
254  }
255 }
256 
257 
258 QString PlaylistContainer::getPlaylistName(int index, bool &reference)
259 {
260  if (m_activePlaylist)
261  {
262  if (m_activePlaylist->getID() == index)
263  {
264  return m_activePlaylist->getName();
265  }
266 
267  QList<Playlist*>::iterator it = m_allPlaylists->begin();
268  for (; it != m_allPlaylists->end(); ++it)
269  {
270  if ((*it)->getID() == index)
271  return (*it)->getName();
272  }
273  }
274 
275  LOG(VB_GENERAL, LOG_ERR, LOC +
276  "getPlaylistName() called with unknown index number");
277 
278  reference = true;
279  return tr("Something is Wrong");
280 }
281 
282 bool PlaylistContainer::nameIsUnique(const QString& a_name, int which_id)
283 {
284  if (a_name == DEFAULT_PLAYLIST_NAME)
285  return false;
286 
287  QList<Playlist*>::iterator it = m_allPlaylists->begin();
288  for (; it != m_allPlaylists->end(); ++it)
289  {
290  if ((*it)->getName() == a_name && (*it)->getID() != which_id)
291  return false;
292  }
293 
294  return true;
295 }
296 
298 {
299  QStringList res;
300 
301  QList<Playlist*>::iterator it = m_allPlaylists->begin();
302  for (; it != m_allPlaylists->end(); ++it)
303  {
304  res.append((*it)->getName());
305  }
306 
307  return res;
308 }
309 
311 {
313  {
314  return true;
315  }
317  return false;
318 }
319 
321 {
323 }
#define DEFAULT_PLAYLIST_NAME
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
Definition: mthread.cpp:215
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:782
void start(QThread::Priority=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
Definition: mthread.cpp:294
QString getPlaylistName(int index, bool &reference)
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:863
PlaylistContainer(AllMusic *all_music)
void describeYourself(void) const
void deletePlaylist(int kill_me)
QStringList getPlaylistNames(void)
void loadPlaylistByID(int id, const QString &a_host)
Definition: playlist.cpp:589
void setParent(PlaylistContainer *myparent)
Definition: playlist.h:50
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:125
bool wait(unsigned long time=ULONG_MAX)
Wait for the MThread to exit, with a maximum timeout.
Definition: mthread.cpp:311
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
QString getName(void)
Definition: playlist.h:103
static void msleep(unsigned long time)
Definition: mthread.cpp:343
Playlist * getPlaylist(int id)
void resync(void)
make sure all tracks are still valid after a scan
Definition: playlist.cpp:617
QVariant value(int i) const
Definition: mythdbcon.h:198
void setName(QString a_name)
Definition: playlist.h:104
void copyNewPlaylist(QString name)
def rating(profile, smoonURL, gate)
Definition: scan.py:25
PlaylistLoadingThread * m_playlistsLoader
#define LOC
void createNewPlaylist(QString name)
bool nameIsUnique(const QString &a_name, int which_id)
void changed(void)
Definition: playlist.cpp:988
static MSqlQueryInfo InitCon(ConnectionReuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:535
Playlist * m_streamPlaylist
int getID(void)
Definition: playlist.h:108
const char * name
Definition: ParseText.cpp:328
void run() override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
void loadPlaylist(const QString &a_name, const QString &a_host)
Definition: playlist.cpp:532
bool doneLoading() const
void copyTracks(Playlist *to_ptr, bool update_display)
Definition: playlist.cpp:43
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:807
Playlist * m_activePlaylist
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
void savePlaylist(const QString &a_name, const QString &a_host)
Definition: playlist.cpp:996
void copyToActive(int index)
QList< Playlist * > * m_allPlaylists
void RunProlog(void)
Sets up a thread, call this if you reimplement run().
Definition: mthread.cpp:202
int numRowsAffected() const
Definition: mythdbcon.h:206
bool isFinished(void) const
Definition: mthread.cpp:269
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:603
void FillIntelliWeights(int &rating, int &playcount, int &lastplay, int &random)
static long int random(void)
Definition: compat.h:149
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:179
void describeYourself(void) const
Definition: playlist.cpp:486
void removeAllTracks(void)
Definition: playlist.cpp:87
void renamePlaylist(int index, QString new_name)
PlaylistContainer * parent
#define DEFAULT_STREAMLIST_NAME