1 /*
2  *  Copyright (C) 2012-2019 Team Kodi
3  *  This file is part of Kodi - https://kodi.tv
4  *
5  *  SPDX-License-Identifier: GPL-2.0-or-later
6  *  See LICENSES/README.md for more information.
7  */
8 
9 #include "PVRGUIChannelIconUpdater.h"
10 
11 #include "FileItem.h"
12 #include "ServiceBroker.h"
13 #include "Util.h"
14 #include "filesystem/Directory.h"
15 #include "filesystem/File.h"
16 #include "guilib/LocalizeStrings.h"
17 #include "pvr/channels/PVRChannel.h"
18 #include "pvr/channels/PVRChannelGroup.h"
19 #include "pvr/guilib/PVRGUIProgressHandler.h"
20 #include "settings/AdvancedSettings.h"
21 #include "settings/Settings.h"
22 #include "settings/SettingsComponent.h"
23 #include "utils/URIUtils.h"
24 #include "utils/log.h"
25 
26 #include <map>
27 #include <string>
28 #include <vector>
29 
30 using namespace PVR;
31 
SearchAndUpdateMissingChannelIcons() const32 void CPVRGUIChannelIconUpdater::SearchAndUpdateMissingChannelIcons() const
33 {
34   const std::string iconPath = CServiceBroker::GetSettingsComponent()->GetSettings()->GetString(CSettings::SETTING_PVRMENU_ICONPATH);
35   if (iconPath.empty())
36     return;
37 
38   // fetch files in icon path for fast lookup
39   CFileItemList fileItemList;
40   XFILE::CDirectory::GetDirectory(iconPath, fileItemList, ".jpg|.png|.tbn", XFILE::DIR_FLAG_DEFAULTS);
41 
42   if (fileItemList.IsEmpty())
43     return;
44 
45   CLog::Log(LOGINFO, "Starting PVR channel icon search");
46 
47   // create a map for fast lookup of normalized file base name
48   std::map<std::string, std::string> fileItemMap;
49   for (const auto& item : fileItemList)
50   {
51     std::string baseName = URIUtils::GetFileName(item->GetPath());
52     URIUtils::RemoveExtension(baseName);
53     StringUtils::ToLower(baseName);
54     fileItemMap.insert({baseName, item->GetPath()});
55   }
56 
57   CPVRGUIProgressHandler* progressHandler = new CPVRGUIProgressHandler(g_localizeStrings.Get(19286)); // Searching for channel icons
58 
59   for (const auto& group : m_groups)
60   {
61     const std::vector<std::shared_ptr<PVRChannelGroupMember>> members = group->GetMembers();
62     int channelIndex = 0;
63     for (const auto& member : members)
64     {
65       progressHandler->UpdateProgress(member->channel->ChannelName(), channelIndex++, members.size());
66 
67       // skip if an icon is already set and exists
68       if (XFILE::CFile::Exists(member->channel->IconPath()))
69         continue;
70 
71       // reset icon before searching for a new one
72       member->channel->SetIconPath("");
73 
74       const std::string strChannelUid = StringUtils::Format("%08d", member->channel->UniqueID());
75       std::string strLegalClientChannelName = CUtil::MakeLegalFileName(member->channel->ClientChannelName());
76       StringUtils::ToLower(strLegalClientChannelName);
77       std::string strLegalChannelName = CUtil::MakeLegalFileName(member->channel->ChannelName());
78       StringUtils::ToLower(strLegalChannelName);
79 
80       std::map<std::string, std::string>::iterator itItem;
81       if ((itItem = fileItemMap.find(strLegalClientChannelName)) != fileItemMap.end() ||
82           (itItem = fileItemMap.find(strLegalChannelName)) != fileItemMap.end() ||
83           (itItem = fileItemMap.find(strChannelUid)) != fileItemMap.end())
84       {
85         member->channel->SetIconPath(itItem->second, CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()->m_bPVRAutoScanIconsUserSet);
86       }
87 
88       if (m_bUpdateDb)
89         member->channel->Persist();
90     }
91   }
92 
93   progressHandler->DestroyProgress();
94 }
95