Go to the documentation of this file.
3 #include <QCoreApplication>
6 #include <QRegularExpression>
27 int sourceid, QString channelname)
29 m_strChannelname(std::move(channelname)), m_fRefresh(fRefresh), m_sourceId(sourceid)
33 LOG(VB_GENERAL, LOG_INFO,
38 LOG(VB_GENERAL, LOG_INFO,
"Fetching icons for multiple channels");
53 QStringList files =
m_tmpDir.entryList();
54 for (
const QString &
file : std::as_const(files))
79 LOG(VB_GENERAL, LOG_ERR,
80 "Unable to load window 'iconimport', missing required element(s)");
191 LOG(VB_GENERAL, LOG_INFO, QString(
"Menu Selection: %1 %2 %3")
192 .arg(entry.strID, entry.strName, entry.strLogo));
253 if (!iconpath.isEmpty())
268 QDir configDir(dirpath);
269 if (!configDir.exists() && !configDir.mkdir(dirpath))
271 LOG(VB_GENERAL, LOG_ERR, QString(
"Could not create %1").arg(dirpath));
279 LOG(VB_GENERAL, LOG_ERR,
284 bool closeDialog =
false;
286 QString querystring(
"SELECT chanid, name, xmltvid, callsign,"
287 "dtv_multiplex.transportid, atsc_major_chan, "
288 "atsc_minor_chan, dtv_multiplex.networkid, "
289 "channel.serviceid, channel.mplexid,"
290 "dtv_multiplex.mplexid, channel.icon, channel.visible "
291 "FROM channel LEFT JOIN dtv_multiplex "
292 "ON channel.mplexid = dtv_multiplex.mplexid "
293 "WHERE deleted IS NULL AND ");
295 querystring.append(
"name=\"" + name +
"\"");
297 querystring.append(
"channel.visible > 0");
299 querystring.append(QString(
" AND channel.sourceid = %1").arg(
m_sourceId));
300 querystring.append(
" ORDER BY name");
310 if (query.
exec() && query.
size() > 0)
320 QCoreApplication::processEvents();
331 QString relativeIconPath = query.
value(11).toString();
335 if (
m_fRefresh && !relativeIconPath.isEmpty() &&
336 QFile(absoluteIconPath).
exists() &&
337 !QImage(absoluteIconPath).isNull())
339 LOG(VB_GENERAL, LOG_NOTICE, QString(
"Icon already exists, skipping (%1)").arg(absoluteIconPath));
352 entry.
strIconCSV= QString(
"%1,%2,%3,%4,%5,%6,%7,%8,%9\n").
363 LOG(VB_CHANNEL, LOG_INFO,
373 QCoreApplication::processEvents();
388 "IconImportInitProgress");
394 QCoreApplication::processEvents();
406 QString downloadMessage = tr(
"Downloading %1 (%2 of %3)");
410 QString message = downloadMessage.arg(
m_iter->strName)
414 LOG(VB_GENERAL, LOG_NOTICE, message);
418 message.append(
"\n");
419 message.append(tr(
"Could not find %n icon(s).",
"",
435 QCoreApplication::processEvents();
456 LOG(VB_CHANNEL, LOG_INFO, QString(
"Icons: Found %1 / Missing %2")
461 (*m_missingIter).strName.isEmpty())
469 LOG(VB_CHANNEL, LOG_INFO,
"doLoad Icon search complete");
476 .arg((*m_missingIter).strName));
478 if (!
search((*m_missingIter).strName))
481 .arg((*m_missingIter).strName));
493 static const QRegularExpression rxDblForEscape(
"\"");
495 str2.replace(rxDblForEscape,
"\\\"");
496 return "\""+str2+
"\"";
503 bool in_comment =
false;
504 bool in_escape =
false;
506 for (
const auto& cur : std::as_const(line))
515 in_comment = !in_comment;
517 else if (cur ==
'\\')
521 else if (!in_comment && (cur ==
','))
536 while (ret.size() < 5)
544 QByteArray data(strParam.toLatin1());
546 auto *req =
new QNetworkRequest(url);
547 req->setHeader(QNetworkRequest::ContentTypeHeader, QString(
"application/x-www-form-urlencoded"));
548 req->setHeader(QNetworkRequest::ContentLengthHeader, data.size());
550 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"ImportIconsWizard: posting to: %1, params: %2")
551 .arg(url.toString(), strParam));
555 LOG(VB_CHANNEL, LOG_DEBUG, QString(
"ImportIconsWizard: result: %1").arg(QString(data)));
562 #include <QTemporaryFile>
565 QString
filename = url.section(
'/', -1);
572 QTemporaryFile tmpFile(filePath);
575 LOG(VB_GENERAL, LOG_INFO,
"Icon Download: Couldn't create temporary file");
583 LOG(VB_GENERAL, LOG_INFO,
584 QString(
"Download for icon %1 failed").arg(
filename));
588 QImage icon(tmpFile.fileName());
591 LOG(VB_GENERAL, LOG_INFO,
592 QString(
"Downloaded icon for %1 isn't a valid image").arg(
filename));
597 QFile
file(filePath);
601 tmpFile.rename(filePath);
602 tmpFile.setAutoRemove(
false);
605 QString qstr =
"UPDATE channel SET icon = :ICON "
606 "WHERE chanid = :CHANID";
623 QString strParam1 = QUrl::toPercentEncoding(
"callsign="+strParam);
624 QUrl url(
m_url+
"/lookup");
626 QString str =
wget(url,strParam1);
627 if (str.isEmpty() || str.startsWith(
"Error", Qt::CaseInsensitive))
629 LOG(VB_GENERAL, LOG_ERR,
630 QString(
"Error from icon lookup : %1").arg(str));
633 LOG(VB_CHANNEL, LOG_INFO,
634 QString(
"Icon Import: Working lookup : %1").arg(str));
641 QString strParam1 = QUrl::toPercentEncoding(strParam);
644 QUrl url(
m_url+
"/search");
647 QString channelcsv = QString(
"%1,%2,%3,%4,%5,%6,%7,%8\n")
657 QString message = QObject::tr(
"Searching for icons for channel %1")
662 QString str =
wget(url,
"s="+strParam1+
"&csv="+channelcsv);
666 if (str.isEmpty() || str.startsWith(
"#") ||
667 str.startsWith(
"Error", Qt::CaseInsensitive))
669 LOG(VB_GENERAL, LOG_ERR, QString(
"Error from search : %1").arg(str));
674 LOG(VB_CHANNEL, LOG_INFO,
675 QString(
"Icon Import: Working search : %1").arg(str));
676 QStringList strSplit = str.split(
"\n");
681 if (strSplit.size() > 150)
683 LOG(VB_GENERAL, LOG_WARNING,
684 QString(
"Warning: Result set contains %1 items, "
685 "truncating to the first %2 results")
686 .arg(strSplit.size()).arg(150));
687 while (strSplit.size() > 150)
688 strSplit.removeLast();
692 QString prevIconName;
695 for (
const QString& row : std::as_const(strSplit))
700 LOG(VB_CHANNEL, LOG_INFO,
701 QString(
"Icon Import: search : %1 %2 %3")
702 .arg(ret[0], ret[1], ret[2]));
704 entry.
strID = ret[0];
710 if (prevIconName == entry.
strName)
712 QString newname = QString(
"%1 (%2)").arg(entry.
strName)
715 QVariant::fromValue(entry));
721 QVariant::fromValue(entry));
725 QString iconname = entry.
strName;
728 item->
SetText(iconname,
"iconname");
743 QString strParam1 = QUrl::toPercentEncoding(strParam);
744 QUrl url(
m_url+
"/findmissing");
746 QString str =
wget(url,
"csv="+strParam1);
747 LOG(VB_CHANNEL, LOG_INFO,
748 QString(
"Icon Import: findmissing : strParam1 = %1. str = %2")
749 .arg(strParam1, str));
750 if (str.isEmpty() || str.startsWith(
"#"))
754 if (str.startsWith(
"Error", Qt::CaseInsensitive))
756 LOG(VB_GENERAL, LOG_ERR,
757 QString(
"Error from findmissing : %1").arg(str));
761 LOG(VB_CHANNEL, LOG_INFO,
762 QString(
"Icon Import: Working findmissing : %1") .arg(str));
763 QStringList strSplit = str.split(
"\n", Qt::SkipEmptyParts);
764 for (
const auto& line : std::as_const(strSplit))
766 if (line[0] == QChar(
'#'))
770 LOG(VB_CHANNEL, LOG_INFO,
771 QString(
"Icon Import: findmissing : %1 %2 %3 %4 %5")
772 .arg(ret[0], ret[1], ret[2], ret[3], ret[4]));
781 QString message = tr(
"You now have the opportunity to transmit your "
782 "choices back to mythtv.org so that others can "
783 "benefit from your selections.");
787 confirmPopup->SetReturnEvent(
this,
"submitresults");
789 if (confirmPopup->Create())
795 QString strParam1 = QUrl::toPercentEncoding(
m_strParam);
796 QUrl url(
m_url+
"/submit");
798 QString str =
wget(url,
"csv="+strParam1);
799 if (str.isEmpty() || str.startsWith(
"#") ||
800 str.startsWith(
"Error", Qt::CaseInsensitive))
802 LOG(VB_GENERAL, LOG_ERR, QString(
"Error from submit : %1").arg(str));
807 LOG(VB_CHANNEL, LOG_INFO, QString(
"Icon Import: Working submit : %1")
809 QStringList strSplit = str.split(
"\n", Qt::SkipEmptyParts);
812 unsigned callsign = 0;
814 unsigned xmltvid = 0;
815 for (
const auto& line : std::as_const(strSplit))
817 if (line[0] == QChar(
'#'))
820 QStringList strSplit2=(line).split(
":", Qt::SkipEmptyParts);
821 if (strSplit2.size() < 2)
824 QString s = strSplit2[0].trimmed();
826 atsc = strSplit2[1].toUInt();
828 callsign = strSplit2[1].toUInt();
830 dvb = strSplit2[1].toUInt();
832 tv = strSplit2[1].toUInt();
834 xmltvid = strSplit2[1].toUInt();
836 LOG(VB_CHANNEL, LOG_INFO,
837 QString(
"Icon Import: working submit : atsc=%1 callsign=%2 "
838 "dvb=%3 tv=%4 xmltvid=%5")
839 .arg(atsc).arg(callsign).arg(dvb).arg(tv).arg(xmltvid));
850 QString resultid = dce->GetId();
851 int buttonnum = dce->GetResult();
853 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
ImportIconsWizard(MythScreenStack *parent, bool fRefresh, int sourceid=0, QString channelname="")
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.
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.
int m_sourceId
selected video source or 0 for all sources
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.