bool ThemeInfo::parseThemeInfo() { QDomDocument doc; if ((m_themeurl.startsWith("http://")) || (m_themeurl.startsWith("https://")) || (m_themeurl.startsWith("ftp://")) || (m_themeurl.startsWith("myth://"))) { QByteArray data; bool ok = GetMythDownloadManager()->download(m_themeurl + "/themeinfo.xml", &data); if (!ok) return false; if (!doc.setContent(data)) { LOG(VB_GENERAL, LOG_ERR, LOC + QString("Unable to parse themeinfo.xml for %1") .arg(m_themeurl)); return false; } } else { QFile f(m_themeurl + "/themeinfo.xml"); if (!f.open(QIODevice::ReadOnly)) { LOG(VB_GENERAL, LOG_WARNING, LOC + QString("Unable to open themeinfo.xml for %1") .arg(f.fileName())); return false; } if (!doc.setContent(&f)) { LOG(VB_GENERAL, LOG_ERR, LOC + QString("Unable to parse themeinfo.xml for %1") .arg(f.fileName())); f.close(); return false; } f.close(); } QDomElement docElem = doc.documentElement(); for (QDomNode n = docElem.firstChild(); !n.isNull(); n = n.nextSibling()) { QDomElement e = n.toElement(); if (!e.isNull()) { if (e.tagName() == "name") { m_name = getFirstText(e); } else if (e.tagName() == "basetheme") { m_baseTheme = getFirstText(e); } else if (e.tagName() == "aspect") { m_aspect = getFirstText(e); } else if (e.tagName() == "baseres") { QString size = getFirstText(e); m_baseres = QSize(size.section('x', 0, 0).toInt(), size.section('x', 1, 1).toInt()); } else if (e.tagName() == "types") { for (QDomNode child = e.firstChild(); !child.isNull(); child = child.nextSibling()) { QDomElement ce = child.toElement(); if (!ce.isNull()) { if (ce.tagName() == "type") { QString type = getFirstText(ce); if (type == "UI") { m_type |= THEME_UI; } else if (type == "OSD") { m_type |= THEME_OSD; } else if (type == "Menu") { m_type |= THEME_MENU; } else { VERBOSE_XML(VB_GENERAL, LOG_ERR, m_theme.fileName(), ce, "Invalid theme type"); } } } } } else if (e.tagName() == "version") { for (QDomNode child = e.firstChild(); !child.isNull(); child = child.nextSibling()) { QDomElement ce = child.toElement(); if (!ce.isNull()) { if (ce.tagName() == "major") { m_majorver = getFirstText(ce).toInt(); } else if (ce.tagName() == "minor") { m_minorver = getFirstText(ce).toInt(); } } } } else if (e.tagName() == "author") { for (QDomNode child = e.firstChild(); !child.isNull(); child = child.nextSibling()) { QDomElement ce = child.toElement(); if (!ce.isNull()) { if (ce.tagName() == "name") { m_authorName = getFirstText(ce); } else if (ce.tagName() == "email") { m_authorEmail = getFirstText(ce); } } } } else if (e.tagName() == "detail") { for (QDomNode child = e.firstChild(); !child.isNull(); child = child.nextSibling()) { QDomElement ce = child.toElement(); if (!ce.isNull()) { if (ce.tagName() == "thumbnail") { if (ce.attribute("name") == "preview") { QString thumbnail = getFirstText(ce); m_previewpath = m_themeurl + '/' + thumbnail; } } else if (ce.tagName() == "description") { m_description = qApp->translate("ThemeUI", parseText(ce).toUtf8()); } else if (ce.tagName() == "errata") { m_errata = qApp->translate("ThemeUI", parseText(ce).toUtf8()); } } } } else if (e.tagName() == "downloadinfo") { for (QDomNode child = e.firstChild(); !child.isNull(); child = child.nextSibling()) { QDomElement ce = child.toElement(); if (!ce.isNull()) { if (ce.tagName() == "url") { m_downloadurl = getFirstText(ce); } } } } } } return true; }
void ChannelData::handleChannels(int id, ChannelInfoList *chanlist) { if (m_guideDataOnly) { LOG(VB_GENERAL, LOG_NOTICE, "Skipping Channel Updates"); return; } ChannelList existingChannels = channelList(id); QString fileprefix = SetupIconCacheDirectory(); QDir::setCurrent(fileprefix); fileprefix += "/"; bool insertChan = insert_chan(id); // unscannable source ChannelInfoList::iterator i = chanlist->begin(); for (; i != chanlist->end(); ++i) { if ((*i).xmltvid.isEmpty()) continue; QString localfile; if (!(*i).icon.isEmpty()) { QDir remotefile = QDir((*i).icon); QString filename = remotefile.dirName(); localfile = fileprefix + filename; QFile actualfile(localfile); if (!actualfile.exists() && !GetMythDownloadManager()->download((*i).icon, localfile)) { LOG(VB_GENERAL, LOG_ERR, QString("Failed to fetch icon from '%1'") .arg((*i).icon)); } localfile = filename; } MSqlQuery query(MSqlQuery::InitCon()); if (!(*i).old_xmltvid.isEmpty()) { query.prepare( "SELECT xmltvid " "FROM channel " "WHERE xmltvid = :XMLTVID"); query.bindValue(":XMLTVID", (*i).old_xmltvid); if (!query.exec()) { MythDB::DBError("xmltvid conversion 1", query); } else if (query.next()) { LOG(VB_GENERAL, LOG_INFO, QString("Converting old xmltvid (%1) to new (%2)") .arg((*i).old_xmltvid).arg((*i).xmltvid)); query.prepare("UPDATE channel " "SET xmltvid = :NEWXMLTVID" "WHERE xmltvid = :OLDXMLTVID"); query.bindValue(":NEWXMLTVID", (*i).xmltvid); query.bindValue(":OLDXMLTVID", (*i).old_xmltvid); if (!query.exec()) { MythDB::DBError("xmltvid conversion 2", query); } } } ChannelInfo dbChan = FindMatchingChannel(*i, existingChannels); if (dbChan.chanid > 0) // Channel exists, updating { LOG(VB_XMLTV, LOG_NOTICE, QString("Match found for xmltvid %1 to channel %2 (%3)") .arg((*i).xmltvid).arg(dbChan.name).arg(dbChan.chanid)); if (m_interactive) { cout << "### " << endl; cout << "### Existing channel found" << endl; cout << "### " << endl; cout << "### xmltvid = " << (*i).xmltvid.toLocal8Bit().constData() << endl; cout << "### chanid = " << dbChan.chanid << endl; cout << "### name = " << dbChan.name.toLocal8Bit().constData() << endl; cout << "### callsign = " << dbChan.callsign.toLocal8Bit().constData() << endl; cout << "### channum = " << dbChan.channum.toLocal8Bit().constData() << endl; if (m_channelPreset) { cout << "### freqid = " << dbChan.freqid.toLocal8Bit().constData() << endl; } cout << "### finetune = " << dbChan.finetune << endl; cout << "### tvformat = " << dbChan.tvformat.toLocal8Bit().constData() << endl; cout << "### icon = " << dbChan.icon.toLocal8Bit().constData() << endl; cout << "### " << endl; // The only thing the xmltv data supplies here is the icon (*i).name = dbChan.name; (*i).callsign = dbChan.callsign; (*i).channum = dbChan.channum; (*i).finetune = dbChan.finetune; (*i).freqid = dbChan.freqid; (*i).tvformat = dbChan.tvformat; promptForChannelUpdates(i, dbChan.chanid); if ((*i).callsign.isEmpty()) (*i).callsign = dbChan.name; if (dbChan.name != (*i).name || dbChan.callsign != (*i).callsign || dbChan.channum != (*i).channum || dbChan.finetune != (*i).finetune || dbChan.freqid != (*i).freqid || dbChan.icon != localfile || dbChan.tvformat != (*i).tvformat) { MSqlQuery subquery(MSqlQuery::InitCon()); subquery.prepare("UPDATE channel SET chanid = :CHANID, " "name = :NAME, callsign = :CALLSIGN, " "channum = :CHANNUM, finetune = :FINE, " "icon = :ICON, freqid = :FREQID, " "tvformat = :TVFORMAT " " WHERE xmltvid = :XMLTVID " "AND sourceid = :SOURCEID;"); subquery.bindValue(":CHANID", dbChan.chanid); subquery.bindValue(":NAME", (*i).name); subquery.bindValue(":CALLSIGN", (*i).callsign); subquery.bindValue(":CHANNUM", (*i).channum); subquery.bindValue(":FINE", (*i).finetune); subquery.bindValue(":ICON", localfile); subquery.bindValue(":FREQID", (*i).freqid); subquery.bindValue(":TVFORMAT", (*i).tvformat); subquery.bindValue(":XMLTVID", (*i).xmltvid); subquery.bindValue(":SOURCEID", id); if (!subquery.exec()) { MythDB::DBError("update failed", subquery); } else { cout << "### " << endl; cout << "### Change performed" << endl; cout << "### " << endl; } } else { cout << "### " << endl; cout << "### Nothing changed" << endl; cout << "### " << endl; } } else if ((dbChan.icon != localfile) || (dbChan.xmltvid != (*i).xmltvid)) { LOG(VB_XMLTV, LOG_NOTICE, QString("Updating channel %1 (%2)") .arg(dbChan.name).arg(dbChan.chanid)); if (localfile.isEmpty()) localfile = dbChan.icon; if (dbChan.xmltvid != (*i).xmltvid) { MSqlQuery subquery(MSqlQuery::InitCon()); subquery.prepare("UPDATE channel SET icon = :ICON " ", xmltvid:= :XMLTVID WHERE " "chanid = :CHANID;"); subquery.bindValue(":ICON", localfile); subquery.bindValue(":XMLTVID", (*i).xmltvid); subquery.bindValue(":CHANID", dbChan.chanid); if (!subquery.exec()) MythDB::DBError("Channel icon change", subquery); } else { MSqlQuery subquery(MSqlQuery::InitCon()); subquery.prepare("UPDATE channel SET icon = :ICON WHERE " "chanid = :CHANID;"); subquery.bindValue(":ICON", localfile); subquery.bindValue(":CHANID", dbChan.chanid); if (!subquery.exec()) MythDB::DBError("Channel icon change", subquery); } } } else if (insertChan) // Only insert channels for non-scannable sources { int major, minor = 0; long long freq = 0; get_atsc_stuff((*i).channum, id, (*i).freqid.toInt(), major, minor, freq); if (m_interactive && ((minor == 0) || (freq > 0))) { cout << "### " << endl; cout << "### New channel found" << endl; cout << "### " << endl; cout << "### name = " << (*i).name.toLocal8Bit().constData() << endl; cout << "### callsign = " << (*i).callsign.toLocal8Bit().constData() << endl; cout << "### channum = " << (*i).channum.toLocal8Bit().constData() << endl; if (m_channelPreset) { cout << "### freqid = " << (*i).freqid.toLocal8Bit().constData() << endl; } cout << "### finetune = " << (*i).finetune << endl; cout << "### tvformat = " << (*i).tvformat.toLocal8Bit().constData() << endl; cout << "### icon = " << localfile.toLocal8Bit().constData() << endl; cout << "### " << endl; uint chanid = promptForChannelUpdates(i,0); if ((*i).callsign.isEmpty()) (*i).callsign = QString::number(chanid); int mplexid = 0; if ((chanid > 0) && (minor > 0)) mplexid = ChannelUtil::CreateMultiplex(id, "atsc", freq, "8vsb"); if (((mplexid > 0) || ((minor == 0) && (chanid > 0))) && ChannelUtil::CreateChannel( mplexid, id, chanid, (*i).callsign, (*i).name, (*i).channum, 0 /*service id*/, major, minor, false /*use on air guide*/, false /*hidden*/, false /*hidden in guide*/, (*i).freqid, localfile, (*i).tvformat, (*i).xmltvid)) { cout << "### " << endl; cout << "### Channel inserted" << endl; cout << "### " << endl; } else { cout << "### " << endl; cout << "### Channel skipped" << endl; cout << "### " << endl; } } else if ((minor == 0) || (freq > 0)) { // We only do this if we are not asked to skip it with the // --update-guide-only (formerly --update) flag. int mplexid = 0, chanid = 0; if (minor > 0) { mplexid = ChannelUtil::CreateMultiplex( id, "atsc", freq, "8vsb"); } if ((mplexid > 0) || (minor == 0)) chanid = ChannelUtil::CreateChanID(id, (*i).channum); if ((*i).callsign.isEmpty()) { QStringList words = (*i).name.simplified().toUpper() .split(" "); QString callsign = ""; QString w1 = words.size() > 0 ? words[0] : QString(); QString w2 = words.size() > 1 ? words[1] : QString(); if (w1.isEmpty()) callsign = QString::number(chanid); else if (w2.isEmpty()) callsign = words[0].left(5); else { callsign = w1.left(w2.length() == 1 ? 4:3); callsign += w2.left(5 - callsign.length()); } (*i).callsign = callsign; } if (chanid > 0) { QString cstr = QString((*i).channum); if(m_channelPreset && cstr.isEmpty()) cstr = QString::number(chanid % 1000); bool retval = ChannelUtil::CreateChannel( mplexid, id, chanid, (*i).callsign, (*i).name, cstr, 0 /*service id*/, major, minor, false /*use on air guide*/, false /*hidden*/, false /*hidden in guide*/, (*i).freqid, localfile, (*i).tvformat, (*i).xmltvid ); if (!retval) cout << "Channel " << chanid << " creation failed" << endl; } } } } }
void ThemeUpdateTask::Terminate(void) { if (m_running) GetMythDownloadManager()->cancelDownload(m_url); m_running = false; }
MythImage *MythUIHelper::LoadCacheImage(QString srcfile, QString label, MythPainter *painter, ImageCacheMode cacheMode) { LOG(VB_GUI | VB_FILE, LOG_INFO, LOC + QString("LoadCacheImage(%1,%2)").arg(srcfile).arg(label)); if (srcfile.isEmpty() || label.isEmpty()) return NULL; if (!(kCacheForceStat & cacheMode)) { // Some screens include certain images dozens or even hundreds of // times. Even if the image is in the cache, there is still a // stat system call on the original file to see if it has changed. // This code relaxes the original-file check so that the check // isn't repeated if it was already done within kImageCacheTimeout // seconds. const uint kImageCacheTimeout = 5; uint now = MythDate::current().toTime_t(); QMutexLocker locker(d->m_cacheLock); if (d->imageCache.contains(label) && d->CacheTrack[label] + kImageCacheTimeout > now) { d->imageCache[label]->IncrRef(); return d->imageCache[label]; } } QString cachefilepath = GetThemeCacheDir() + '/' + label; QFileInfo fi(cachefilepath); MythImage *ret = NULL; if (!!(cacheMode & kCacheIgnoreDisk) || fi.exists()) { // Now compare the time on the source versus our cached copy if (!(cacheMode & kCacheIgnoreDisk)) FindThemeFile(srcfile); QDateTime srcLastModified; QFileInfo original(srcfile); if ((srcfile.startsWith("http://")) || (srcfile.startsWith("https://")) || (srcfile.startsWith("ftp://"))) { srcLastModified = GetMythDownloadManager()->GetLastModified(srcfile); } else if (srcfile.startsWith("myth://")) srcLastModified = RemoteFile::LastModified(srcfile); else if (original.exists()) srcLastModified = original.lastModified(); if (!!(cacheMode & kCacheIgnoreDisk) || (fi.lastModified() > srcLastModified)) { // Check Memory Cache ret = GetImageFromCache(label); if (!ret && (cacheMode == kCacheNormal) && painter) { // Load file from disk cache to memory cache ret = painter->GetFormatImage(); if (!ret->Load(cachefilepath, false)) { LOG(VB_GUI | VB_FILE, LOG_WARNING, LOC + QString("LoadCacheImage: Could not load :%1") .arg(cachefilepath)); ret->SetIsInCache(false); ret->DecrRef(); ret = NULL; } else { // Add to ram cache, and skip saving to disk since that is // where we found this in the first place. CacheImage(label, ret, true); } } } else { // If file has changed on disk, then remove it from the memory // and disk cache RemoveFromCacheByURL(label); } } return ret; }
QImage *MythUIHelper::LoadScaleImage(QString filename, bool fromcache) { LOG(VB_GUI | VB_FILE, LOG_INFO, LOC + QString("LoadScaleImage(%1)").arg(filename)); if (filename.isEmpty()) return NULL; if ((!FindThemeFile(filename)) && (!filename.startsWith("http://")) && (!filename.startsWith("https://")) && (!filename.startsWith("ftp://")) && (!filename.startsWith("myth://"))) { LOG(VB_GENERAL, LOG_ERR, LOC + QString("LoadScaleImage(%1) ") .arg(filename) + "Unable to find image file"); return NULL; } QImage *ret = NULL; QImage tmpimage; int width, height; float wmult, hmult; GetScreenSettings(width, wmult, height, hmult); if (filename.startsWith("myth://")) { RemoteFile *rf = new RemoteFile(filename, false, false, 0); QByteArray data; bool loaded = rf->SaveAs(data); delete rf; if (loaded) tmpimage.loadFromData(data); else { LOG(VB_GENERAL, LOG_ERR, LOC + QString("LoadScaleImage(%1) failed to load remote image") .arg(filename)); } } else if ((filename.startsWith("http://")) || (filename.startsWith("https://")) || (filename.startsWith("ftp://"))) { QByteArray data; if (GetMythDownloadManager()->download(filename, &data)) tmpimage.loadFromData(data); else { LOG(VB_GENERAL, LOG_ERR, LOC + QString("LoadScaleImage(%1) failed to load remote image") .arg(filename)); } } else { tmpimage.load(filename); } if (width != d->m_baseWidth || height != d->m_baseHeight) { if (tmpimage.isNull()) { LOG(VB_GENERAL, LOG_ERR, LOC + QString("LoadScaleImage(%1) failed to load image") .arg(filename)); return NULL; } QImage tmp2 = tmpimage.scaled( (int)(tmpimage.width() * wmult), (int)(tmpimage.height() * hmult), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); ret = new QImage(tmp2); } else { ret = new QImage(tmpimage); if (!ret->width() || !ret->height()) { LOG(VB_GENERAL, LOG_ERR, LOC + QString("LoadScaleImage(%1) invalid image dimensions") .arg(filename)); delete ret; return NULL; } } return ret; }
void ThemeChooser::customEvent(QEvent *e) { if ((MythEvent::Type)(e->type()) == MythEvent::MythEventMessage) { MythEvent *me = (MythEvent *)e; QStringList tokens = me->Message().split(" ", QString::SkipEmptyParts); if (tokens.isEmpty()) return; if (tokens[0] == "DOWNLOAD_FILE") { QStringList args = me->ExtraDataList(); if ((m_downloadState == dsIdle) || (tokens.size() != 2) || (!m_downloadTheme) || (args[1] != m_downloadFile)) return; if (tokens[1] == "UPDATE") { updateProgressBar(args[2].toInt(), args[3].toInt()); } else if (tokens[1] == "FINISHED") { bool remoteFileIsLocal = false; int fileSize = args[2].toInt(); int errorCode = args[4].toInt(); CloseBusyPopup(); QFileInfo file(m_downloadFile); if ((m_downloadState == dsDownloadingOnBackend) && (m_downloadFile.startsWith("myth://"))) { // The backend download is finished so start the // frontend download if ((errorCode == 0) && (fileSize > 0)) { m_downloadState = dsDownloadingOnFrontend; QString localFile = GetConfDir() + "/tmp/" + file.fileName(); file.setFile(localFile); if (file.exists()) { remoteFileIsLocal = true; } else { GetMythDownloadManager()->queueDownload( m_downloadFile, localFile, this); OpenBusyPopup(tr("Copying %1 Theme Package") .arg(m_downloadTheme->GetName())); } m_downloadFile = localFile; } else { m_downloadState = dsIdle; ShowOkPopup(tr("ERROR downloading theme package on master backend.")); } } if ((m_downloadState == dsDownloadingOnFrontend) && (file.exists())) { // The frontend download is finished if ((errorCode == 0) && (fileSize > 0)) { m_downloadState = dsExtractingTheme; ThemeExtractThread *extractThread = new ThemeExtractThread(this, m_downloadFile, GetConfDir() + "/themes"); QThreadPool::globalInstance()->start(extractThread); if (!remoteFileIsLocal) RemoteFile::DeleteFile(args[0]); OpenBusyPopup(tr("Installing %1 Theme") .arg(m_downloadTheme->GetName())); } else { m_downloadState = dsIdle; ShowOkPopup(tr("ERROR downloading theme package from master backend.")); } } } } else if ((me->Message() == "THEME_INSTALLED") && (m_downloadTheme) && (m_downloadState == dsExtractingTheme)) { m_downloadState = dsIdle; CloseBusyPopup(); QStringList args = me->ExtraDataList(); QFile::remove(args[0]); QString event = QString("THEME_INSTALLED PATH %1") .arg(GetConfDir() + "/themes/" + m_downloadTheme->GetDirectoryName()); SendMythSystemEvent(event); gCoreContext->SaveSetting("Theme", m_downloadTheme->GetDirectoryName()); GetMythMainWindow()->JumpTo("Reload Theme"); } } }
void ThemeChooser::Load(void) { SetBusyPopupMessage(tr("Loading Installed Themes")); QString MythVersion = MYTH_SOURCE_PATH; QStringList themesSeen; QDir themes(GetConfDir() + "/themes"); themes.setFilter(QDir::Dirs | QDir::NoDotAndDotDot); themes.setSorting(QDir::Name | QDir::IgnoreCase); // FIXME: For now, treat git master the same as svn trunk if (MythVersion == "master") MythVersion = "trunk"; if (MythVersion != "trunk") { MythVersion = MYTH_BINARY_VERSION; // Example: 0.25.20101017-1 MythVersion.replace(QRegExp("\\.[0-9]{8,}.*"), ""); } m_infoList = themes.entryInfoList(); for( QFileInfoList::iterator it = m_infoList.begin(); it != m_infoList.end(); ++it ) { if (loadThemeInfo(*it)) { themesSeen << (*it).fileName(); m_themeStatuses[(*it).fileName()] = "default"; } } themes.setPath(GetThemesParentDir()); QFileInfoList sharedThemes = themes.entryInfoList(); for( QFileInfoList::iterator it = sharedThemes.begin(); it != sharedThemes.end(); ++it ) { if ((!themesSeen.contains((*it).fileName())) && (loadThemeInfo(*it))) { m_infoList << *it; themesSeen << (*it).fileName(); m_themeStatuses[(*it).fileName()] = "default"; } } QString remoteThemesFile = GetConfDir(); remoteThemesFile.append("/tmp/themes.zip"); QString themeSite = QString("%1/%2") .arg(gCoreContext->GetSetting("ThemeRepositoryURL", "http://themes.mythtv.org/themes/repository")).arg(MythVersion); int downloadFailures = gCoreContext->GetNumSetting("ThemeInfoDownloadFailures", 0); if (QFile::exists(remoteThemesFile)) { QFileInfo finfo(remoteThemesFile); if (finfo.lastModified() < mythCurrentDateTime().addSecs(-600)) { VERBOSE(VB_GUI, LOC + QString("%1 is over 10 minutes old, forcing " "remote theme list download").arg(remoteThemesFile)); m_refreshDownloadableThemes = true; } } else if (downloadFailures < 2) // (and themes.zip does not exist) { VERBOSE(VB_GUI, LOC + QString("%1 does not exist, forcing remote theme " "list download").arg(remoteThemesFile)); m_refreshDownloadableThemes = true; } if (m_refreshDownloadableThemes) { SetBusyPopupMessage(tr("Refreshing Downloadable Themes Information")); QString url = themeSite; url.append("/themes.zip"); QString destdir = GetMythUI()->GetThemeCacheDir(); destdir.append("/themechooser"); QString versiondir = QString("%1/%2").arg(destdir).arg(MythVersion); removeThemeDir(versiondir); QDir dir; dir.mkpath(destdir); bool result = GetMythDownloadManager()->download(url, remoteThemesFile); SetBusyPopupMessage(tr("Extracting Downloadable Themes Information")); if (!result || !extractZIP(remoteThemesFile, destdir)) { QFile::remove(remoteThemesFile); downloadFailures++; gCoreContext->SaveSetting("ThemeInfoDownloadFailures", downloadFailures); } } QDir remoteThemesDir(GetMythUI()->GetThemeCacheDir() .append("/themechooser/").append(MythVersion)); if ((QFile::exists(remoteThemesFile)) && (remoteThemesDir.exists())) { SetBusyPopupMessage(tr("Loading Downloadable Themes")); VERBOSE(VB_GUI, LOC + QString("%1 and %2 exist, using cached remote " "themes list").arg(remoteThemesFile) .arg(remoteThemesDir.absolutePath())); QString themesPath = remoteThemesDir.absolutePath(); themes.setPath(themesPath); QFileInfoList downloadableThemes = themes.entryInfoList(); for( QFileInfoList::iterator it = downloadableThemes.begin(); it != downloadableThemes.end(); ++it ) { QString dirName = (*it).fileName(); QString themeName = dirName; QString remoteDir = themeSite; remoteDir.append("/").append(dirName); QString localDir = themes.absolutePath(); localDir.append("/").append(dirName); if (themesSeen.contains(dirName)) { ThemeInfo remoteTheme((*it).absoluteFilePath()); ThemeInfo *localTheme = m_themeNameInfos[dirName]; themeName = remoteTheme.GetName(); int rmtMaj = remoteTheme.GetMajorVersion(); int rmtMin = remoteTheme.GetMinorVersion(); int locMaj = localTheme->GetMajorVersion(); int locMin = localTheme->GetMinorVersion(); if ((rmtMaj > locMaj) || ((rmtMaj == locMaj) && (rmtMin > locMin))) { if (loadThemeInfo(*it)) { m_infoList << *it; m_themeStatuses[themeName] = "updateavailable"; QFileInfo finfo(remoteTheme.GetPreviewPath()); GetMythDownloadManager()->queueDownload( remoteDir.append("/").append(finfo.fileName()), localDir.append("/").append(finfo.fileName()), NULL); } } else if ((rmtMaj == locMaj) && (rmtMin == locMin)) { m_themeStatuses[themeName] = "uptodate"; } } else { ThemeInfo *remoteTheme = loadThemeInfo(*it); if (remoteTheme) { themeName = remoteTheme->GetName(); themesSeen << dirName; m_infoList << *it; m_themeStatuses[themeName] = "updateavailable"; QFileInfo finfo(remoteTheme->GetPreviewPath()); GetMythDownloadManager()->queueDownload( remoteDir.append("/").append(finfo.fileName()), localDir.append("/").append(finfo.fileName()), NULL); } } } } ResetBusyPopup(); qSort(m_infoList.begin(), m_infoList.end(), sortThemeNames); }
MythWebPage::~MythWebPage() { LOG(VB_GENERAL, LOG_DEBUG, "Refreshing DLManager's Cookie Jar"); GetMythDownloadManager()->refreshCookieJar(networkManager->cookieJar()); GetMythDownloadManager()->saveCookieJar(GetConfDir() + "/MythBrowser/cookiejar.txt"); }