2 * Copyright (C) 2012-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
9 #include "FileExtensionProvider.h"
11 #include "ServiceBroker.h"
12 #include "addons/AddonEvents.h"
13 #include "addons/AddonManager.h"
14 #include "addons/AudioDecoder.h"
15 #include "addons/ExtsMimeSupportList.h"
16 #include "addons/ImageDecoder.h"
17 #include "addons/addoninfo/AddonInfo.h"
18 #include "addons/addoninfo/AddonType.h"
19 #include "settings/AdvancedSettings.h"
20 #include "settings/SettingsComponent.h"
21 #include "utils/URIUtils.h"
26 using namespace ADDON
;
27 using namespace KODI::ADDONS
;
29 const std::vector
<AddonType
> ADDON_TYPES
= {AddonType::VFS
, AddonType::IMAGEDECODER
,
30 AddonType::AUDIODECODER
};
32 CFileExtensionProvider::CFileExtensionProvider(ADDON::CAddonMgr
& addonManager
)
33 : m_advancedSettings(CServiceBroker::GetSettingsComponent()->GetAdvancedSettings()),
34 m_addonManager(addonManager
)
38 m_addonManager
.Events().Subscribe(this, &CFileExtensionProvider::OnAddonEvent
);
41 CFileExtensionProvider::~CFileExtensionProvider()
43 m_addonManager
.Events().Unsubscribe(this);
45 m_advancedSettings
.reset();
46 m_addonExtensions
.clear();
49 std::string
CFileExtensionProvider::GetDiscStubExtensions() const
51 return m_advancedSettings
->m_discStubExtensions
;
54 std::string
CFileExtensionProvider::GetMusicExtensions() const
56 std::string
extensions(m_advancedSettings
->m_musicExtensions
);
57 extensions
+= '|' + GetAddonExtensions(AddonType::VFS
);
58 extensions
+= '|' + GetAddonExtensions(AddonType::AUDIODECODER
);
63 std::string
CFileExtensionProvider::GetPictureExtensions() const
65 std::string
extensions(m_advancedSettings
->m_pictureExtensions
);
66 extensions
+= '|' + GetAddonExtensions(AddonType::VFS
);
67 extensions
+= '|' + GetAddonExtensions(AddonType::IMAGEDECODER
);
72 std::string
CFileExtensionProvider::GetSubtitleExtensions() const
74 std::string
extensions(m_advancedSettings
->m_subtitlesExtensions
);
75 extensions
+= '|' + GetAddonExtensions(AddonType::VFS
);
80 std::string
CFileExtensionProvider::GetVideoExtensions() const
82 std::string
extensions(m_advancedSettings
->m_videoExtensions
);
83 if (!extensions
.empty())
85 extensions
+= GetAddonExtensions(AddonType::VFS
);
90 std::string
CFileExtensionProvider::GetFileFolderExtensions() const
92 std::string
extensions(GetAddonFileFolderExtensions(AddonType::VFS
));
93 if (!extensions
.empty())
95 extensions
+= GetAddonFileFolderExtensions(AddonType::AUDIODECODER
);
100 bool CFileExtensionProvider::CanOperateExtension(const std::string
& path
) const
103 * @todo Improve this function to support all cases and not only audio decoder.
106 // Get file extensions to find addon related to it.
107 std::string strExtension
= URIUtils::GetExtension(path
);
108 StringUtils::ToLower(strExtension
);
109 if (!strExtension
.empty() && CServiceBroker::IsAddonInterfaceUp())
111 std::vector
<std::unique_ptr
<KODI::ADDONS::IAddonSupportCheck
>> supportList
;
113 auto addonInfos
= CServiceBroker::GetExtsMimeSupportList().GetExtensionSupportedAddonInfos(
114 strExtension
, CExtsMimeSupportList::FilterSelect::all
);
115 for (const auto& addonInfo
: addonInfos
)
117 switch (addonInfo
.first
)
119 case AddonType::AUDIODECODER
:
120 supportList
.emplace_back(new CAudioDecoder(addonInfo
.second
));
122 case AddonType::IMAGEDECODER
:
123 supportList
.emplace_back(new CImageDecoder(addonInfo
.second
, ""));
131 * We expect that other addons can support the file, and return true if
134 * @todo Check addons can also be types in conflict with Kodi's
137 * @warning This part is really big ugly at the moment and as soon as possible
138 * add about other addons where works with extensions!!!
139 * Due to @ref GetFileFolderExtensions() call from outside place before here, becomes
140 * it usable in this way, as there limited to AudioDecoder and VFS addons.
142 if (supportList
.empty())
148 * Check all found addons about support of asked file.
150 for (const auto& addon
: supportList
)
152 if (addon
->SupportsFile(path
))
158 * If no file extensions present, mark it as not supported.
163 std::string
CFileExtensionProvider::GetAddonExtensions(AddonType type
) const
165 auto it
= m_addonExtensions
.find(type
);
166 if (it
!= m_addonExtensions
.end())
172 std::string
CFileExtensionProvider::GetAddonFileFolderExtensions(AddonType type
) const
174 auto it
= m_addonFileFolderExtensions
.find(type
);
175 if (it
!= m_addonFileFolderExtensions
.end())
181 void CFileExtensionProvider::SetAddonExtensions()
183 for (auto const type
: ADDON_TYPES
)
185 SetAddonExtensions(type
);
189 void CFileExtensionProvider::SetAddonExtensions(AddonType type
)
191 std::vector
<std::string
> extensions
;
192 std::vector
<std::string
> fileFolderExtensions
;
194 if (type
== AddonType::AUDIODECODER
|| type
== AddonType::IMAGEDECODER
)
196 auto addonInfos
= CServiceBroker::GetExtsMimeSupportList().GetSupportedAddonInfos(
197 CExtsMimeSupportList::FilterSelect::all
);
198 for (const auto& addonInfo
: addonInfos
)
200 if (addonInfo
.m_addonType
!= type
)
203 for (const auto& ext
: addonInfo
.m_supportedExtensions
)
205 extensions
.push_back(ext
.first
);
206 if (addonInfo
.m_hasTracks
)
207 fileFolderExtensions
.push_back(ext
.first
);
211 else if (type
== AddonType::VFS
)
213 std::vector
<AddonInfoPtr
> addonInfos
;
214 m_addonManager
.GetAddonInfos(addonInfos
, true, type
);
215 for (const auto& addonInfo
: addonInfos
)
217 std::string ext
= addonInfo
->Type(type
)->GetValue("@extensions").asString();
220 extensions
.push_back(ext
);
221 if (addonInfo
->Type(type
)->GetValue("@filedirectories").asBoolean())
222 fileFolderExtensions
.push_back(ext
);
224 if (addonInfo
->Type(type
)->GetValue("@encodedhostname").asBoolean())
226 std::string prot
= addonInfo
->Type(type
)->GetValue("@protocols").asString();
227 auto prots
= StringUtils::Split(prot
, "|");
228 for (const std::string
& it
: prots
)
229 m_encoded
.push_back(it
);
235 m_addonExtensions
[type
] = StringUtils::Join(extensions
, "|");
236 m_addonFileFolderExtensions
[type
] = StringUtils::Join(fileFolderExtensions
, "|");
239 void CFileExtensionProvider::OnAddonEvent(const AddonEvent
& event
)
241 if (typeid(event
) == typeid(AddonEvents::Enabled
) ||
242 typeid(event
) == typeid(AddonEvents::Disabled
) ||
243 typeid(event
) == typeid(AddonEvents::ReInstalled
))
245 for (auto &type
: ADDON_TYPES
)
247 if (m_addonManager
.HasType(event
.addonId
, type
))
249 SetAddonExtensions(type
);
254 else if (typeid(event
) == typeid(AddonEvents::UnInstalled
))
256 SetAddonExtensions();
260 bool CFileExtensionProvider::EncodedHostName(const std::string
& protocol
) const
262 return std::find(m_encoded
.begin(),m_encoded
.end(),protocol
) != m_encoded
.end();