MythTV  master
restoredata.cpp
Go to the documentation of this file.
1 /*
2  * $Id$
3  * vim: set expandtab tabstop=4 shiftwidth=4:
4  *
5  * Original Project
6  * MythTV http://www.mythtv.org
7  *
8  * Description:
9  * Restore data from deleted channels after scan for new channels
10  *
11  * When all channels are deleted and a new scan is done then
12  * all the non-scanned data is lost.
13  * This are the following fields:
14  * xmltvid Channel identification for XMLTV including Schedules Direct
15  * iconpath File name of icon for this channel
16  * visible Visible status
17  * When a channel is deleted it is not immediately deleted from the database;
18  * it is kept for a while with the "deleted" field set to the date at which it
19  * is deleted.
20  * This makes it possible to retrieve this data from the deleted records
21  * when the same channel is found again in a new scan.
22  *
23  * This program is free software; you can redistribute it and/or
24  * modify it under the terms of the GNU General Public License
25  * as published by the Free Software Foundation; either version 2
26  * of the License, or (at your option) any later version.
27  *
28  * This program is distributed in the hope that it will be useful,
29  * but WITHOUT ANY WARRANTY; without even the implied warranty of
30  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31  * GNU General Public License for more details.
32  *
33  * You should have received a copy of the GNU General Public License
34  * along with this program; if not, write to the Free Software
35  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
36  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
37  *
38  */
39 
40 // C++ includes
41 #include <vector>
42 #include <iostream>
43 
44 // MythTV includes
46 #include "libmythbase/mythdb.h"
48 #include "libmythui/mythuiimage.h"
49 #include "libmythui/mythuitext.h"
50 #include "libmythui/themeinfo.h"
51 
52 #include "restoredata.h"
53 #include "sourceutil.h"
54 #include "videosource.h"
55 
56 #define LOC QString("RestoreData: ")
57 
59 {
60  public:
62  {
63  setLabel(QObject::tr("Restore XMLTV ID"));
65  QObject::tr(
66  "If checked, copy the XMLTV ID in field \"xmltvid\" "
67  "from a deleted channel "
68  "or from a channel in another video source."));
69  setValue(false);
70  };
71 };
72 
74 {
75  public:
77  {
78  setLabel(QObject::tr("Restore Visible status"));
80  QObject::tr(
81  "If checked, copy the Visible status in field \"visible\" "
82  "from a deleted channel in this video source."));
83  setValue(false);
84  };
85 };
86 
88 {
89  public:
91  {
92  setLabel(QObject::tr("Restore Icon filename"));
94  QObject::tr(
95  "If checked, copy the Icon filename in field \"icon\" "
96  "from a deleted channel "
97  "or from a channel in another video source."));
98  setValue(false);
99  };
100 };
101 
103 
105 {
106  if (s_Instance != nullptr)
107  {
108  if (sourceid != s_Instance->m_sourceid)
109  {
110  delete s_Instance;
111  s_Instance = nullptr;
112  }
113  }
114  if (s_Instance == nullptr)
115  s_Instance = new RestoreData(sourceid, false);
116  return s_Instance;
117 }
118 
120 {
121  if (s_Instance != nullptr)
122  {
123  delete s_Instance;
124  s_Instance = nullptr;
125  }
126 }
127 
128 RestoreData::RestoreData(uint sourceid, bool useGUI) :
129  m_sourceid(sourceid), m_useGUI(useGUI)
130 {
131  if (!m_useGUI)
132  return;
133  setLabel(tr("Restore Data"));
134 
137  QObject::tr(
138  "The video source is selected in the Channel Editor page. "
139  "Searching for non-scanned data is done for all channels in this video source."
140  ));
142 
145 
148 
149  m_restoreIcon = new RestoreIcon();
151 
152  auto *newTransport = new ButtonStandardSetting(tr("Search"));
153  newTransport->setHelpText(
154  QObject::tr(
155  "Start searching for non-scanned data. The data is written to the database "
156  "when \'Save and Exit\' is selected in the \'Exit Settings?\' dialog box."
157  ));
158  addChild(newTransport);
159  connect(newTransport, &ButtonStandardSetting::clicked, this, &RestoreData::Restore);
160 }
161 
163 {
164  if (!m_useGUI)
165  return;
166  bool do_xmltvid = m_restoreXMLTVID->boolValue();
167  bool do_icon = m_restoreIcon->boolValue();
168  bool do_visible = m_restoreVisible->boolValue();
169  doRestore(do_xmltvid, do_icon, do_visible);
170 }
171 
172 QString RestoreData::doRestore(bool do_xmltvid, bool do_icon, bool do_visible)
173 {
174  if (do_xmltvid || do_icon || do_visible)
175  {
176  QString msg = QString("Restore data from deleted channels for fields ");
177  if (do_xmltvid)
178  {
179  msg += "xmltvid ";
180  }
181  if (do_icon)
182  {
183  msg += "icon ";
184  }
185  if (do_visible)
186  {
187  msg += "visible ";
188  }
189  LOG(VB_GENERAL, LOG_INFO, LOC + msg);
190  }
191 
192  // Old Channel Data
193  m_ocd.clear();
194 
195  MSqlQuery query(MSqlQuery::InitCon());
196  MSqlQuery query2(MSqlQuery::InitCon());
197 
198  // For all channels in this videosource
199  query.prepare(
200  "SELECT chanid, channum, name, serviceid, transportid, networkid, "
201  " channel.xmltvid, "
202  " channel.icon, "
203  " channel.visible "
204  "FROM channel, dtv_multiplex "
205  "WHERE channel.sourceid = :SOURCEID "
206  " AND channel.mplexid = dtv_multiplex.mplexid "
207  " AND deleted IS NULL ");
208  query.bindValue(":SOURCEID", m_sourceid);
209  if (!query.exec() || !query.isActive())
210  {
211  MythDB::DBError("RestoreData::Restore(1)", query);
212  return QString();
213  }
214  while (query.next())
215  {
216  OldChannelData cd;
217  cd.chanid = query.value(0).toUInt();
218  cd.channum = query.value(1).toString();
219  cd.name = query.value(2).toString();
220  cd.serviceid = query.value(3).toUInt();
221  cd.transportid = query.value(4).toUInt();
222  cd.networkid = query.value(5).toUInt();
223  cd.xmltvid = query.value(6).toString();
224  cd.icon = query.value(7).toString();
225  cd.visible = query.value(8).toInt();
226 
227  bool nullNetwork = query.isNull(5);
228  cd.found_xmltvid = false;
229  cd.found_icon = false;
230  cd.found_visible = false;
231 
232  QString networkCheck;
233  if (nullNetwork)
234  networkCheck = " networkid IS NULL";
235  else
236  networkCheck = " networkid = :NETWORKID ";
237 
238  // Get xmltvid from the last deleted channel
239  // from any video source or from a channel
240  // on a different video source
241  if (do_xmltvid && cd.xmltvid.isEmpty())
242  {
243  query2.prepare(
244  "SELECT xmltvid "
245  "FROM channel, dtv_multiplex "
246  "WHERE serviceid = :SERVICEID "
247  " AND transportid = :TRANSPORTID "
248  " AND " + networkCheck +
249  " AND channel.mplexid = dtv_multiplex.mplexid "
250  " AND xmltvid != ''"
251  " AND (deleted IS NOT NULL OR "
252  " channel.sourceid != :SOURCEID)"
253  "ORDER BY deleted DESC;");
254  query2.bindValue(":SERVICEID", cd.serviceid);
255  query2.bindValue(":TRANSPORTID", cd.transportid);
256  if (!nullNetwork)
257  query2.bindValue(":NETWORKID", cd.networkid);
258  query2.bindValue(":SOURCEID", m_sourceid);
259  if (!query2.exec() || !query2.isActive())
260  {
261  MythDB::DBError("RestoreData::Restore(2)", query);
262  return QString();
263  }
264  if (query2.next())
265  {
266  cd.xmltvid = query2.value(0).toString();
267  cd.found_xmltvid = true;
268  }
269  }
270 
271  // Get icon from the last deleted channel
272  // from any video source or from a channel
273  // on a different video source
274  if (do_icon && cd.icon.isEmpty())
275  {
276  query2.prepare(
277  "SELECT icon "
278  "FROM channel, dtv_multiplex "
279  "WHERE serviceid = :SERVICEID "
280  " AND transportid = :TRANSPORTID "
281  " AND channel.mplexid = dtv_multiplex.mplexid "
282  " AND icon != ''"
283  " AND (deleted IS NOT NULL OR "
284  " channel.sourceid != :SOURCEID)"
285  "ORDER BY deleted DESC;");
286  query2.bindValue(":SERVICEID", cd.serviceid);
287  query2.bindValue(":TRANSPORTID", cd.transportid);
288  if (!nullNetwork)
289  query2.bindValue(":NETWORKID", cd.networkid);
290  query2.bindValue(":SOURCEID", m_sourceid);
291  if (!query2.exec() || !query2.isActive())
292  {
293  MythDB::DBError("RestoreData::Restore(3)", query);
294  return QString();
295  }
296  if (query2.next())
297  {
298  cd.icon = query2.value(0).toString();
299  cd.found_icon = true;
300  }
301  }
302 
303  // Get visible from the last deleted channel
304  // but only from the same video source
305  if (do_visible)
306  {
307  query2.prepare(
308  "SELECT channel.visible "
309  "FROM channel, dtv_multiplex "
310  "WHERE serviceid = :SERVICEID "
311  " AND transportid = :TRANSPORTID "
312  " AND " + networkCheck +
313  " AND channel.sourceid = :SOURCEID "
314  " AND channel.mplexid = dtv_multiplex.mplexid "
315  " AND deleted IS NOT NULL "
316  "ORDER BY deleted DESC;");
317  query2.bindValue(":SERVICEID", cd.serviceid);
318  query2.bindValue(":TRANSPORTID", cd.transportid);
319  if (!nullNetwork)
320  query2.bindValue(":NETWORKID", cd.networkid);
321  query2.bindValue(":SOURCEID", m_sourceid);
322  if (!query2.exec() || !query2.isActive())
323  {
324  MythDB::DBError("RestoreData::Restore(4)", query);
325  return QString();
326  }
327  if (query2.next())
328  {
329  int visible = query2.value(0).toInt();
330  if (visible != cd.visible)
331  {
332  cd.visible = visible;
333  cd.found_visible = true;
334  }
335  }
336  }
337 
338  if (cd.found_xmltvid || cd.found_icon || cd.found_visible)
339  {
340  m_ocd.push_back(cd);
341  }
342  }
343 
344  // Header line for log of all changes
345  if (m_ocd.empty())
346  {
347  LOG(VB_GENERAL, LOG_INFO, LOC + "No data found in deleted channels or no data needed");
348  }
349  else
350  {
351  LOG(VB_GENERAL, LOG_INFO, LOC +
352  QString("Restoring data in %1 channels from deleted channels:")
353  .arg(m_ocd.size()));
354  }
355 
356  // Log of all channels that will be updated
357  m_num_xmltvid = 0;
358  m_num_icon = 0;
359  m_num_visible = 0;
360  for (auto & cd : m_ocd)
361  {
362  QString msg = QString("Channel %1 \'%2\' update ").arg(cd.channum, cd.name);
363  if (cd.found_xmltvid)
364  {
365  msg += QString("xmltvid(%1) ").arg(cd.xmltvid);
366  m_num_xmltvid++;
367  }
368  if (cd.found_icon)
369  {
370  msg += QString("icon(%1) ").arg(cd.icon);
371  m_num_icon++;
372  }
373  if (cd.found_visible)
374  {
375  msg += QString("visible(%1) ").arg(cd.visible);
376  m_num_visible++;
377  }
378  LOG(VB_GENERAL, LOG_INFO, LOC + msg);
379  }
380  m_num_channels = m_ocd.size();
381 
382  // Show totals of what has been found.
383  {
384  QString msg;
385  if (m_ocd.empty())
386  {
387  msg = "No data found";
388  }
389  else
390  {
391  msg = QString("Found data for %1 channels\n").arg(m_ocd.size());
392  if (m_num_xmltvid > 0)
393  {
394  msg += QString("xmltvid: %1 ").arg(m_num_xmltvid);
395  }
396  if (m_num_icon > 0)
397  {
398  msg += QString("icon: %1 ").arg(m_num_icon);
399  }
400  if (m_num_visible > 0)
401  {
402  msg += QString("visible: %1").arg(m_num_visible);
403  }
404  }
405  if (m_useGUI)
406  WaitFor(ShowOkPopup(msg));
407  return msg;
408  }
409 
410 }
411 
412 // Load value of selected video source (for display only)
414 {
416 }
417 
418 // Do the actual updating if "Save and Exit" is selected in the "Exit Settings?" dialog.
420 {
421  doSave();
422 }
423 
425 {
426  if (m_ocd.empty())
427  {
428  LOG(VB_GENERAL, LOG_INFO, LOC + QString("No data to Restore"));
429  return false;
430  }
431  MSqlQuery query(MSqlQuery::InitCon());
432  for (auto & cd : m_ocd)
433  {
434  query.prepare(
435  "UPDATE channel "
436  "SET icon = :ICON, "
437  " xmltvid = :XMLTVID, "
438  " visible = :VISIBLE "
439  "WHERE chanid = :CHANID");
440  query.bindValue(":ICON", cd.icon);
441  query.bindValue(":XMLTVID", cd.xmltvid);
442  query.bindValue(":VISIBLE", cd.visible);
443  query.bindValue(":CHANID", cd.chanid);
444  if (!query.exec() || !query.isActive())
445  {
446  MythDB::DBError("RestoreData::Restore(5)", query);
447  return false;
448  }
449  }
450  LOG(VB_GENERAL, LOG_INFO, LOC + QString("Restored data for %1 channels").arg(m_ocd.size()));
451  return true;
452 }
RestoreData::doSave
bool doSave(void)
Definition: restoredata.cpp:424
RestoreData::m_num_visible
int m_num_visible
Definition: restoredata.h:114
MSqlQuery::isActive
bool isActive(void) const
Definition: mythdbcon.h:215
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:813
WaitFor
bool WaitFor(MythConfirmationDialog *dialog)
Blocks until confirmation dialog exits.
Definition: mythdialogbox.cpp:599
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:127
RestoreData::s_Instance
static RestoreData * s_Instance
Definition: restoredata.h:98
RestoreData::m_videosource
VideoSourceShow * m_videosource
Definition: restoredata.h:99
TransMythUICheckBoxSetting
Definition: standardsettings.h:411
mythuitext.h
MSqlQuery::isNull
bool isNull(int field) const
Definition: mythdbcon.h:219
RestoreData::m_num_icon
int m_num_icon
Definition: restoredata.h:113
RestoreData
Definition: restoredata.h:82
OldChannelData::found_visible
bool found_visible
Definition: restoredata.h:76
mythdb.h
RestoreData::m_num_xmltvid
int m_num_xmltvid
Definition: restoredata.h:112
OldChannelData::channum
QString channum
Definition: restoredata.h:68
ButtonStandardSetting
Definition: standardsettings.h:450
RestoreData::m_useGUI
bool m_useGUI
Definition: restoredata.h:105
LOC
#define LOC
Definition: restoredata.cpp:56
RestoreData::m_sourceid
uint m_sourceid
Definition: restoredata.h:104
mythdialogbox.h
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:204
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:619
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
RestoreData::m_ocd
std::vector< OldChannelData > m_ocd
Definition: restoredata.h:107
mythuiimage.h
OldChannelData::visible
int visible
Definition: restoredata.h:72
ButtonStandardSetting::clicked
void clicked()
OldChannelData::icon
QString icon
Definition: restoredata.h:71
RestoreData::doRestore
QString doRestore(bool do_xmltvid, bool do_icon, bool do_visible)
Definition: restoredata.cpp:172
StandardSetting::addChild
virtual void addChild(StandardSetting *child)
Definition: standardsettings.cpp:71
sourceutil.h
RestoreXMLTVID::RestoreXMLTVID
RestoreXMLTVID()
Definition: restoredata.cpp:61
themeinfo.h
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:551
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:226
restoredata.h
StandardSetting::Load
virtual void Load(void)
Definition: standardsettings.cpp:214
OldChannelData::transportid
uint transportid
Definition: restoredata.h:66
StandardSetting::setHelpText
virtual void setHelpText(const QString &str)
Definition: standardsettings.h:37
OldChannelData::found_icon
bool found_icon
Definition: restoredata.h:75
RestoreData::m_restoreXMLTVID
RestoreXMLTVID * m_restoreXMLTVID
Definition: restoredata.h:100
OldChannelData::chanid
uint chanid
Definition: restoredata.h:63
uint
unsigned int uint
Definition: compat.h:81
RestoreData::m_num_channels
int m_num_channels
Definition: restoredata.h:111
OldChannelData::name
QString name
Definition: restoredata.h:69
RestoreData::m_restoreVisible
RestoreVisible * m_restoreVisible
Definition: restoredata.h:101
OldChannelData::found_xmltvid
bool found_xmltvid
Definition: restoredata.h:74
StandardSetting::setLabel
virtual void setLabel(QString str)
Definition: standardsettings.h:34
VideoSourceShow
Definition: videosource.h:76
RestoreData::Restore
void Restore(void)
Definition: restoredata.cpp:162
RestoreData::RestoreData
RestoreData(uint sourceid, bool useGUI=true)
Definition: restoredata.cpp:128
mythcorecontext.h
RestoreXMLTVID
Definition: restoredata.cpp:58
OldChannelData
Definition: restoredata.h:61
RestoreData::Load
void Load(void) override
Definition: restoredata.cpp:413
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:889
OldChannelData::serviceid
uint serviceid
Definition: restoredata.h:65
RestoreData::Save
void Save(void) override
Definition: restoredata.cpp:419
RestoreIcon::RestoreIcon
RestoreIcon()
Definition: restoredata.cpp:90
OldChannelData::networkid
uint networkid
Definition: restoredata.h:67
OldChannelData::xmltvid
QString xmltvid
Definition: restoredata.h:70
RestoreIcon
Definition: restoredata.cpp:87
RestoreData::m_restoreIcon
RestoreIcon * m_restoreIcon
Definition: restoredata.h:102
RestoreData::getInstance
static RestoreData * getInstance(uint sourceid)
Definition: restoredata.cpp:104
RestoreVisible
Definition: restoredata.cpp:73
RestoreVisible::RestoreVisible
RestoreVisible()
Definition: restoredata.cpp:76
RestoreData::freeInstance
static void freeInstance()
Definition: restoredata.cpp:119
MythUICheckBoxSetting::setValue
void setValue(const QString &newValue) override
Definition: standardsettings.cpp:721
ShowOkPopup
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
Definition: mythdialogbox.cpp:562
videosource.h
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:838
MythUICheckBoxSetting::boolValue
bool boolValue()
Definition: standardsettings.h:403