Go to the documentation of this file.
3 #include <QCoreApplication>
6 #include <QRegularExpression>
30 m_strChannelname(
std::move(channelname)), m_fRefresh(fRefresh)
34 LOG(VB_GENERAL, LOG_INFO,
39 LOG(VB_GENERAL, LOG_INFO,
"Fetching icons for multiple channels");
54 QStringList files =
m_tmpDir.entryList();
55 for (
const QString &
file : qAsConst(files))
80 LOG(VB_GENERAL, LOG_ERR,
81 "Unable to load window 'iconimport', missing required element(s)");
192 LOG(VB_GENERAL, LOG_INFO, QString(
"Menu Selection: %1 %2 %3")
193 .arg(entry.strID, entry.strName, entry.strLogo));
254 if (!iconpath.isEmpty())
269 QDir configDir(dirpath);
270 if (!configDir.exists() && !configDir.mkdir(dirpath))
272 LOG(VB_GENERAL, LOG_ERR, QString(
"Could not create %1").arg(dirpath));
280 LOG(VB_GENERAL, LOG_ERR,
285 bool closeDialog =
false;
287 QString querystring(
"SELECT chanid, name, xmltvid, callsign,"
288 "dtv_multiplex.transportid, atsc_major_chan, "
289 "atsc_minor_chan, dtv_multiplex.networkid, "
290 "channel.serviceid, channel.mplexid,"
291 "dtv_multiplex.mplexid, channel.icon, channel.visible "
292 "FROM channel LEFT JOIN dtv_multiplex "
293 "ON channel.mplexid = dtv_multiplex.mplexid "
294 "WHERE deleted IS NULL AND ");
296 querystring.append(
"name=\"" + name +
"\"");
298 querystring.append(
"channel.visible > 0");
299 querystring.append(
" ORDER BY name");
309 if (query.
exec() && query.
size() > 0)
319 QCoreApplication::processEvents();
330 QString relativeIconPath = query.
value(11).toString();
334 if (
m_fRefresh && !relativeIconPath.isEmpty() &&
335 QFile(absoluteIconPath).exists() &&
336 !QImage(absoluteIconPath).isNull())
338 LOG(VB_GENERAL, LOG_NOTICE, QString(
"Icon already exists, skipping (%1)").arg(absoluteIconPath));
351 entry.
strIconCSV= QString(
"%1,%2,%3,%4,%5,%6,%7,%8,%9\n").
362 LOG(VB_CHANNEL, LOG_INFO,
372 QCoreApplication::processEvents();
387 "IconImportInitProgress");
393 QCoreApplication::processEvents();
404 QString downloadMessage = tr(
"Downloading %1 of %2");
408 QString message = downloadMessage.arg(
m_nCount+1)
411 LOG(VB_GENERAL, LOG_NOTICE, message);
415 message.append(
"\n");
416 message.append(tr(
"Could not find %n icon(s).",
"",
432 QCoreApplication::processEvents();
453 LOG(VB_CHANNEL, LOG_INFO, QString(
"Icons: Found %1 / Missing %2")
458 (*m_missingIter).strName.isEmpty())
466 LOG(VB_CHANNEL, LOG_INFO,
"doLoad Icon search complete");
473 .arg((*m_missingIter).strName));
475 if (!
search((*m_missingIter).strName))
478 .arg((*m_missingIter).strName));
490 static const QRegularExpression rxDblForEscape(
"\"");
492 str2.replace(rxDblForEscape,
"\\\"");
493 return "\""+str2+
"\"";
500 bool in_comment =
false;
501 bool in_escape =
false;
503 for (
const auto& cur : qAsConst(line))
512 in_comment = !in_comment;
514 else if (cur ==
'\\')
518 else if (!in_comment && (cur ==
','))
533 while (ret.size() < 5)
541 QByteArray data(strParam.toLatin1());
543 auto *req =
new QNetworkRequest(url);
544 req->setHeader(QNetworkRequest::ContentTypeHeader, QString(
"application/x-www-form-urlencoded"));
545 req->setHeader(QNetworkRequest::ContentLengthHeader, data.size());
547 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"ImportIconsWizard: posting to: %1, params: %2")
548 .arg(url.toString(), strParam));
552 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"ImportIconsWizard: result: %1").arg(QString(data)));
559 #include <QTemporaryFile>
562 QString
filename = url.section(
'/', -1);
569 QTemporaryFile tmpFile(filePath);
572 LOG(VB_GENERAL, LOG_INFO,
"Icon Download: Couldn't create temporary file");
580 LOG(VB_GENERAL, LOG_INFO,
581 QString(
"Download for icon %1 failed").arg(
filename));
585 QImage icon(tmpFile.fileName());
588 LOG(VB_GENERAL, LOG_INFO,
589 QString(
"Downloaded icon for %1 isn't a valid image").arg(
filename));
594 QFile
file(filePath);
598 tmpFile.rename(filePath);
599 tmpFile.setAutoRemove(
false);
602 QString qstr =
"UPDATE channel SET icon = :ICON "
603 "WHERE chanid = :CHANID";
620 QString strParam1 = QUrl::toPercentEncoding(
"callsign="+strParam);
621 QUrl url(
m_url+
"/lookup");
623 QString str =
wget(url,strParam1);
624 if (str.isEmpty() || str.startsWith(
"Error", Qt::CaseInsensitive))
626 LOG(VB_GENERAL, LOG_ERR,
627 QString(
"Error from icon lookup : %1").arg(str));
630 LOG(VB_CHANNEL, LOG_INFO,
631 QString(
"Icon Import: Working lookup : %1").arg(str));
638 QString strParam1 = QUrl::toPercentEncoding(strParam);
641 QUrl url(
m_url+
"/search");
644 QString channelcsv = QString(
"%1,%2,%3,%4,%5,%6,%7,%8\n")
654 QString message = QObject::tr(
"Searching for icons for channel %1")
659 QString str =
wget(url,
"s="+strParam1+
"&csv="+channelcsv);
663 if (str.isEmpty() || str.startsWith(
"#") ||
664 str.startsWith(
"Error", Qt::CaseInsensitive))
666 LOG(VB_GENERAL, LOG_ERR, QString(
"Error from search : %1").arg(str));
671 LOG(VB_CHANNEL, LOG_INFO,
672 QString(
"Icon Import: Working search : %1").arg(str));
673 QStringList strSplit = str.split(
"\n");
678 if (strSplit.size() > 150)
680 LOG(VB_GENERAL, LOG_WARNING,
681 QString(
"Warning: Result set contains %1 items, "
682 "truncating to the first %2 results")
683 .arg(strSplit.size()).arg(150));
684 while (strSplit.size() > 150)
685 strSplit.removeLast();
689 QString prevIconName;
692 for (
const QString& row : qAsConst(strSplit))
697 LOG(VB_CHANNEL, LOG_INFO,
698 QString(
"Icon Import: search : %1 %2 %3")
699 .arg(ret[0], ret[1], ret[2]));
701 entry.
strID = ret[0];
707 if (prevIconName == entry.
strName)
709 QString newname = QString(
"%1 (%2)").arg(entry.
strName)
712 QVariant::fromValue(entry));
718 QVariant::fromValue(entry));
722 QString iconname = entry.
strName;
725 item->
SetText(iconname,
"iconname");
740 QString strParam1 = QUrl::toPercentEncoding(strParam);
741 QUrl url(
m_url+
"/findmissing");
743 QString str =
wget(url,
"csv="+strParam1);
744 LOG(VB_CHANNEL, LOG_INFO,
745 QString(
"Icon Import: findmissing : strParam1 = %1. str = %2")
746 .arg(strParam1, str));
747 if (str.isEmpty() || str.startsWith(
"#"))
751 if (str.startsWith(
"Error", Qt::CaseInsensitive))
753 LOG(VB_GENERAL, LOG_ERR,
754 QString(
"Error from findmissing : %1").arg(str));
758 LOG(VB_CHANNEL, LOG_INFO,
759 QString(
"Icon Import: Working findmissing : %1") .arg(str));
760 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
761 QStringList strSplit = str.split(
"\n", QString::SkipEmptyParts);
763 QStringList strSplit = str.split(
"\n", Qt::SkipEmptyParts);
765 for (
const auto& line : qAsConst(strSplit))
767 if (line[0] == QChar(
'#'))
771 LOG(VB_CHANNEL, LOG_INFO,
772 QString(
"Icon Import: findmissing : %1 %2 %3 %4 %5")
773 .arg(ret[0], ret[1], ret[2], ret[3], ret[4]));
782 QString message = tr(
"You now have the opportunity to transmit your "
783 "choices back to mythtv.org so that others can "
784 "benefit from your selections.");
788 confirmPopup->SetReturnEvent(
this,
"submitresults");
790 if (confirmPopup->Create())
796 QString strParam1 = QUrl::toPercentEncoding(
m_strParam);
797 QUrl url(
m_url+
"/submit");
799 QString str =
wget(url,
"csv="+strParam1);
800 if (str.isEmpty() || str.startsWith(
"#") ||
801 str.startsWith(
"Error", Qt::CaseInsensitive))
803 LOG(VB_GENERAL, LOG_ERR, QString(
"Error from submit : %1").arg(str));
808 LOG(VB_CHANNEL, LOG_INFO, QString(
"Icon Import: Working submit : %1")
810 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
811 QStringList strSplit = str.split(
"\n", QString::SkipEmptyParts);
813 QStringList strSplit = str.split(
"\n", Qt::SkipEmptyParts);
817 unsigned callsign = 0;
819 unsigned xmltvid = 0;
820 for (
const auto& line : qAsConst(strSplit))
822 if (line[0] == QChar(
'#'))
825 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
826 QStringList strSplit2=(line).split(
":", QString::SkipEmptyParts);
828 QStringList strSplit2=(line).split(
":", Qt::SkipEmptyParts);
830 if (strSplit2.size() < 2)
833 QString s = strSplit2[0].trimmed();
835 atsc = strSplit2[1].toUInt();
837 callsign = strSplit2[1].toUInt();
839 dvb = strSplit2[1].toUInt();
841 tv = strSplit2[1].toUInt();
843 xmltvid = strSplit2[1].toUInt();
845 LOG(VB_CHANNEL, LOG_INFO,
846 QString(
"Icon Import: working submit : atsc=%1 callsign=%2 "
847 "dvb=%3 tv=%4 xmltvid=%5")
848 .arg(atsc).arg(callsign).arg(dvb).arg(tv).arg(xmltvid));
859 QString resultid = dce->GetId();
860 int buttonnum = dce->GetResult();
862 if (resultid ==
"submitresults")
void Reset(void) override
Reset the widget to it's original state, should not reset changes made by the theme.
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
QSqlQuery wrapper that fetches a DB connection from the connection pool.
bool Create(void) override
QString strCallsign
callsign
Image widget, displays a single image or multiple images in sequence.
void Reset(void) override
Reset the widget to it's original state, should not reset changes made by the theme.
QString strName
the remote name
void itemChanged(MythUIButtonListItem *item)
static QString escape_csv(const QString &str)
changes a string into csv format
MythScreenStack * m_popupStack
MythUIType * GetChild(const QString &name) const
Get a named child of this UIType.
bool Load(bool allowLoadInBackground=true, bool forceStat=false)
Load the image(s), wraps ImageLoader::LoadImage()
QString strNameCSV
name (csv form)
QString m_strChannelname
the channel name if searching for a single channel icon
QVariant value(int i) const
int m_missingCount
the current search point (0..m_missingCount)
bool doLoad()
attempts to move the iteration on one/more than one
bool Create(void) override
bool search(const QString &strParam)
search the remote db for icons etc
QString strServiceId
service id
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
A text entry and edit widget.
void OpenBusyPopup(const QString &message="")
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
static QStringList extract_csv(const QString &strLine)
extracts the csv values out of a string
Screen in which all other widgets are contained and rendered.
int m_nCount
the current search point (0..m_nMaxCount)
QString GetText(void) const
QString strIconCSV
icon name (csv form)
void Reset(void) override
Reset the image back to the default defined in the theme.
void SetMessage(const QString &message)
MythUIButton * m_manualButton
manual button field
bool initialLoad(const QString &name="")
attempt the inital load of the TV channel information
ListEntriesIter m_iter
the current iterator
int m_nMaxCount
the maximum number of TV channels
MythUIButtonList * m_iconsList
list of potential icons
ListEntries m_listEntries
list of TV channels to search for
QString strName
channel name
void SetText(const QString &text, bool moveCursor=true)
QString strNetworkId
network id
bool lookup(const QString &strParam)
looks up the string to determine the caller/xmltvid
bool SetFocusWidget(MythUIType *widget=nullptr)
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
static void DBError(const QString &where, const MSqlQuery &query)
QString m_strChannelDir
the location of the channel icon dir
ListEntries m_missingEntries
list of TV channels with no unique icon
void SetProgress(uint count)
void SetHelpText(const QString &text)
void enableControls(ImportIconsWizard::dialogState state=STATE_NORMAL)
enable/disable the controls
void BuildFocusList(void)
MythUITextEdit * m_manualEdit
manual edit field
bool download(const QString &url, const QString &dest, bool reload=false)
Downloads a URL to a file in blocking mode.
MythUIProgressDialog * m_progressDialog
void skip()
skip this icon
void SetEnabled(bool enable)
QString strXmlTvId
the xmltvid
ListEntriesIter m_missingIter
ListSearchEntries m_listSearch
the list of SearchEntry
describes the TV channel name
bool checkAndDownload(const QString &url, const QString &localChanId)
checks and attempts to download the logo file to the appropriate place
~ImportIconsWizard() override
QString m_strMatches
the string for the submit() call
All purpose text widget, displays a text string.
ImportIconsWizard(MythScreenStack *parent, bool fRefresh, QString channelname="")
static QString wget(QUrl &url, const QString &strParam)
use the equivalent of wget to fetch the POST command
Dialog asking for user confirmation. Ok and optional Cancel button.
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
MythUIText * m_statusText
void askSubmit(const QString &strParam)
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
void SetTotal(uint total)
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
QString strAtscMajorChan
ATSC major number.
MythUIText * m_previewtitle
virtual void SetText(const QString &text)
QString strChanId
local channel id
static const Type kEventType
MythMainWindow * GetMythMainWindow(void)
int m_missingMaxCount
the total number of missing icons
QString strLogo
the actual logo
void customEvent(QEvent *event) override
void menuSelection(MythUIButtonListItem *item)
process the icon selection
void manualSearch()
process the manual search
QString strTransportId
transport id
MythScreenStack * GetStack(const QString &Stackname)
MythUIText * m_nameText
name field for the icon
bool m_fRefresh
are we doing a refresh or not
MythUIButton * m_skipButton
button skip
void SetFilename(const QString &filename)
Must be followed by a call to Load() to load the image.
bool submit()
submit the icon information back to the remote db
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
QString strAtscMinorChan
ATSC minor number.
void CloseBusyPopup(void)
void Load(void) override
Load data which will ultimately be displayed on-screen or used to determine what appears on-screen (S...
bool findmissing(const QString &strParam)
retrieve the actual logo for the TV channel
void Init(void) override
Used after calling Load() to assign data to widgets and other UI initilisation which is prohibited in...
QString strID
the remote channel id
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.