From 3074732c8da922ca8fa6426064a62d4a05aae8a6 Mon Sep 17 00:00:00 2001
From: Sascha Hinck <SHinck@web.de>
Date: Sat, 25 Aug 2012 18:21:05 +0200
Subject: [PATCH] Cache channelicons in local folder on remote frontends

If channelicons are not in local folder $(ConfDIR)/channels they will be
fetched from backend StorageGroup ChannelIcons an cached in local folder
on first showing in the program guide.
---
 mythtv/libs/libmythtv/dbchannelinfo.cpp        |   82 ++++++++++++++++++++++++
 mythtv/libs/libmythtv/dbchannelinfo.h          |    3 +
 mythtv/libs/libmythtv/osd.cpp                  |   15 +++--
 mythtv/programs/mythfilldatabase/icondata.cpp  |    2 +-
 mythtv/programs/mythfrontend/guidegrid.cpp     |   20 +++---
 mythtv/programs/mythtv-setup/channeleditor.cpp |   14 ++++-
 mythtv/programs/mythtv-setup/importicons.cpp   |    2 +-
 7 files changed, 118 insertions(+), 20 deletions(-)

diff --git a/mythtv/libs/libmythtv/dbchannelinfo.cpp b/mythtv/libs/libmythtv/dbchannelinfo.cpp
index 2e9086a..b0caa68 100644
--- a/mythtv/libs/libmythtv/dbchannelinfo.cpp
+++ b/mythtv/libs/libmythtv/dbchannelinfo.cpp
@@ -102,6 +102,88 @@ QString DBChannel::GetFormatted(const ChannelFormat &format) const
 ////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////
 
+bool DBChannel::CacheChannelIcon(void)
+{
+    if (icon.isEmpty())
+        return false;
+
+    m_localIcon = icon;
+
+    // Is icon local?
+    if (QFile(icon).exists())
+        return true;
+
+    QString localDirStr = QString("%1/channels").arg(GetConfDir());
+    QDir localDir(localDirStr);
+
+    if (!localDir.exists() && !localDir.mkdir(localDirStr))
+    {
+        LOG(VB_GENERAL, LOG_ERR,
+            QString("Icons directory is missing and could not be created: %1")
+                .arg(localDirStr));
+        icon.clear();
+        return false;
+    }
+
+    // Has it been saved to the local cache?
+    m_localIcon = QString("%1/%2").arg(localDirStr)
+                                 .arg(QFileInfo(icon).fileName());
+    if (QFile(m_localIcon).exists())
+        return true;
+
+    // Get address of master backed
+    QString url = gCoreContext->GetMasterHostPrefix("ChannelIcons",
+										icon);
+    if (url.length() < 1)
+    {
+        icon.clear();
+        return false;
+    }
+
+    QUrl qurl = url;
+    if (qurl.host().isEmpty())
+    {
+        icon.clear();
+        return false;
+    }
+
+    RemoteFile *rf = new RemoteFile(url, false, false, 0);
+
+    QByteArray data;
+    bool ret = rf->SaveAs(data);
+
+    delete rf;
+
+    if (ret && data.size())
+    {
+        QImage image;
+
+        image.loadFromData(data);
+
+        //if (image.loadFromData(data) && image.width() > 0
+
+        if (image.save(m_localIcon))
+        {
+            LOG(VB_GENERAL, LOG_INFO,
+                QString("Caching channel icon %1").arg(m_localIcon));
+            return true;
+        }
+        else
+            LOG(VB_GENERAL, LOG_ERR,
+                QString("Failed to save to %1").arg(m_localIcon));
+    }
+
+    // if we get here then the icon is set in the db but couldn't be found
+    // anywhere so maybe we should remove it from the DB?
+    icon.clear();
+
+    return false;
+}
+
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+
+
 QString ChannelInfo::GetFormatted(const ChannelFormat &format) const
 {
     QString tmp;
diff --git a/mythtv/libs/libmythtv/dbchannelinfo.h b/mythtv/libs/libmythtv/dbchannelinfo.h
index 3e4b6ea..991b8b2 100644
--- a/mythtv/libs/libmythtv/dbchannelinfo.h
+++ b/mythtv/libs/libmythtv/dbchannelinfo.h
@@ -33,6 +33,8 @@ class MTV_PUBLIC DBChannel
     bool operator == (uint _chanid) const
         { return chanid == _chanid; }
 
+    bool CacheChannelIcon(void);
+
     enum ChannelFormat { kChannelShort, kChannelLong };
     QString GetFormatted(const ChannelFormat &format) const;
     void ToMap(InfoMap &infoMap) const;
@@ -42,6 +44,7 @@ class MTV_PUBLIC DBChannel
     QString callsign;
     QString name;
     QString icon;
+    QString m_localIcon;
     uint    chanid;
     uint    major_chan;
     uint    minor_chan;
diff --git a/mythtv/libs/libmythtv/osd.cpp b/mythtv/libs/libmythtv/osd.cpp
index 5703ed3..694d18f 100644
--- a/mythtv/libs/libmythtv/osd.cpp
+++ b/mythtv/libs/libmythtv/osd.cpp
@@ -4,6 +4,9 @@
 // libmyth
 #include "mythlogging.h"
 
+// libmythbase
+#include "mythdirs.h"
+
 // libmythui
 #include "mythmainwindow.h"
 #include "mythuihelper.h"
@@ -436,14 +439,14 @@ void OSD::SetText(const QString &window, QHash<QString,QString> &map,
                 iconpath = map["iconpath"];
             else
                 iconpath = ChannelUtil::GetIcon(chanid);
+		
+		QString localIcon = QString("%1/channels/%2").arg(GetConfDir())
+                                 		.arg(QFileInfo(iconpath).fileName());
 
-            if (!iconpath.isEmpty())
-            {
-                QString iconurl =
-                                gCoreContext->GetMasterHostPrefix("ChannelIcons",
-                                                                  iconpath);
 
-                icon->SetFilename(iconurl);
+            if (QFile(localIcon).exists())
+            {
+                icon->SetFilename(localIcon);
                 icon->Load(false);
             }
         }
diff --git a/mythtv/programs/mythfilldatabase/icondata.cpp b/mythtv/programs/mythfilldatabase/icondata.cpp
index 95e44d9..1e47ee3 100644
--- a/mythtv/programs/mythfilldatabase/icondata.cpp
+++ b/mythtv/programs/mythfilldatabase/icondata.cpp
@@ -316,7 +316,7 @@ bool IconData::Save(const FI &fi, const QByteArray &data)
         "UPDATE channel SET icon = :ICON "
         "WHERE chanid = :CHANID");
 
-    update.bindValue(":ICON",     fi.filename);
+    update.bindValue(":ICON", QFileInfo(fi.filename).fileName());
     update.bindValue(":CHANID",   fi.chanid);
 
     if (!update.exec())
diff --git a/mythtv/programs/mythfrontend/guidegrid.cpp b/mythtv/programs/mythfrontend/guidegrid.cpp
index 24e1956..1990c4e 100644
--- a/mythtv/programs/mythfrontend/guidegrid.cpp
+++ b/mythtv/programs/mythfrontend/guidegrid.cpp
@@ -1576,12 +1576,11 @@ void GuideGrid::updateChannels(void)
             chinfo->ToMap(infomap);
             item->SetTextFromMap(infomap);
 
-            if (!chinfo->icon.isEmpty())
+            if (!chinfo->icon.isEmpty() &&
+                chinfo->CacheChannelIcon())
             {
-                QString iconurl =
-                                gCoreContext->GetMasterHostPrefix("ChannelIcons",
-                                                                  chinfo->icon);
-                item->SetImage(iconurl, "channelicon");
+                QString localpath = chinfo->m_localIcon;
+                item->SetImage(localpath, "channelicon");
             }
         }
     }
@@ -1613,11 +1612,12 @@ void GuideGrid::updateInfo(void)
         m_channelImage->Reset();
         if (!chinfo->icon.isEmpty())
         {
-            QString iconurl = gCoreContext->GetMasterHostPrefix("ChannelIcons",
-                                                                chinfo->icon);
-
-            m_channelImage->SetFilename(iconurl);
-            m_channelImage->Load();
+            if (chinfo->CacheChannelIcon())
+            {
+                QString localpath = chinfo->m_localIcon;
+                m_channelImage->SetFilename(localpath);
+                m_channelImage->Load();
+            }
         }
     }
 
diff --git a/mythtv/programs/mythtv-setup/channeleditor.cpp b/mythtv/programs/mythtv-setup/channeleditor.cpp
index f93c03b..9ea11db 100644
--- a/mythtv/programs/mythtv-setup/channeleditor.cpp
+++ b/mythtv/programs/mythtv-setup/channeleditor.cpp
@@ -4,6 +4,7 @@
 // MythTV
 #include "mythprogressdialog.h"
 #include "mythuibuttonlist.h"
+#include "mythcorecontext.h"
 #include "channelsettings.h"
 #include "transporteditor.h"
 #include "mythuicheckbox.h"
@@ -210,7 +211,10 @@ void ChannelEditor::itemChanged(MythUIButtonListItem *item)
         QString iconpath = item->GetImageFilename();
         if (!iconpath.isEmpty())
         {
-            m_preview->SetFilename(iconpath);
+            QString iconurl = gCoreContext->GetMasterHostPrefix("ChannelIcons",
+                                                               iconpath);
+
+            m_preview->SetFilename(iconurl);
             m_preview->Load();
         }
     }
@@ -336,7 +340,13 @@ void ChannelEditor::fillList(void)
             item->SetText(callsign, "callsign");
             item->SetText(sourceid, "sourcename");
             item->SetImage(icon);
-            item->SetImage(icon, "icon");
+            if (!icon.isEmpty())
+            {
+                QString iconurl =
+                                gCoreContext->GetMasterHostPrefix("ChannelIcons",
+                                                                  	icon);
+                item->SetImage(iconurl, "icon");
+            }
             item->DisplayState(state, "status");
         }
     }
diff --git a/mythtv/programs/mythtv-setup/importicons.cpp b/mythtv/programs/mythtv-setup/importicons.cpp
index 4fe041b..3cce488 100644
--- a/mythtv/programs/mythtv-setup/importicons.cpp
+++ b/mythtv/programs/mythtv-setup/importicons.cpp
@@ -553,7 +553,7 @@ bool ImportIconsWizard::checkAndDownload(const QString& url, const QString& loca
                         "WHERE chanid = :CHANID";
 
         query.prepare(qstr);
-        query.bindValue(":ICON", file.absoluteFilePath());
+        query.bindValue(":ICON", file.fileName());
         query.bindValue(":CHANID", localChanId);
 
         if (!query.exec())
